ISSUE ID:- (RICAPP-176).
[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  mdclog_write(MDCLOG_INFO,"instance id for subsreq  = %d", ricrequest_ie->ricInstanceID);
179   //ricrequest_ie->ricRequestSequenceNumber = helper.get_req_seq();
180   result = ASN_SEQUENCE_ADD(&(ric_subscription->protocolIEs), &IE_array[ie_index]);
181   assert(result == 0);
182      
183   ie_index = 1;
184   RICsubscriptionRequest_IEs_t *ies_ranfunc = &IE_array[ie_index];
185   ies_ranfunc->criticality = Criticality_reject;
186   ies_ranfunc->id = ProtocolIE_ID_id_RANfunctionID;
187   ies_ranfunc->value.present = RICsubscriptionRequest_IEs__value_PR_RANfunctionID;
188   RANfunctionID_t *ranfunction_ie = &ies_ranfunc->value.choice.RANfunctionID;
189   *ranfunction_ie = helper.get_function_id();
190   result = ASN_SEQUENCE_ADD(&(ric_subscription->protocolIEs), &IE_array[ie_index]);
191   assert(result == 0);
192
193
194   ie_index = 2;
195   RICsubscriptionRequest_IEs_t *ies_actid = &IE_array[ie_index];
196   ies_actid->criticality = Criticality_reject;
197   ies_actid->id = ProtocolIE_ID_id_RICsubscriptionDetails;
198   ies_actid->value.present = RICsubscriptionRequest_IEs__value_PR_RICsubscriptionDetails;
199   RICsubscriptionDetails_t *ricsubscription_ie = &ies_actid->value.choice.RICsubscriptionDetails;
200
201   ricsubscription_ie->ricEventTriggerDefinition.buf = (uint8_t *) helper.get_event_def();
202   ricsubscription_ie->ricEventTriggerDefinition.size = helper.get_event_def_size();
203    
204   std::vector<Action> * ref_action_array = helper.get_list();
205   // do we need to resize  ?
206   // we don't care about contents, so just do a free/calloc
207   if(action_array_size < ref_action_array->size()){
208     std::cout <<"re-allocating action array from " << action_array_size << " to " << 2 * ref_action_array->size() <<  std::endl;
209     // free subsequent allocation
210     for (unsigned int i = 0; i < action_array_size; i++){
211       free(action_array[i].value.choice.RICaction_ToBeSetup_Item.ricSubsequentAction );
212     }
213     
214     action_array_size = 2 * ref_action_array->size();
215     free(action_array);
216     action_array = (RICaction_ToBeSetup_ItemIEs_t *)calloc(action_array_size, sizeof(RICaction_ToBeSetup_ItemIEs_t));
217     assert(action_array != 0);
218
219     // also need to add subsequent action and time to wait ..
220     for (unsigned int i = 0; i < action_array_size; i++){
221       action_array[i].value.choice.RICaction_ToBeSetup_Item.ricSubsequentAction = (struct RICsubsequentAction *)calloc(1, sizeof(struct RICsubsequentAction));
222       assert(action_array[i].value.choice.RICaction_ToBeSetup_Item.ricSubsequentAction  != 0);
223     }
224     
225   }
226   
227   // reset the list count on ricAction_ToBeSetup_List;
228   ricsubscription_ie->ricAction_ToBeSetup_List.list.count = 0;
229   
230   for(unsigned int i = 0; i < ref_action_array->size(); i ++){
231     action_array[i].criticality = Criticality_ignore;
232     action_array[i].id = ProtocolIE_ID_id_RICaction_ToBeSetup_Item ;
233     action_array[i].value.present = RICaction_ToBeSetup_ItemIEs__value_PR_RICaction_ToBeSetup_Item;
234     action_array[i].value.choice.RICaction_ToBeSetup_Item.ricActionID = (*ref_action_array)[i].get_id();
235     action_array[i].value.choice.RICaction_ToBeSetup_Item.ricActionType = (*ref_action_array)[i].get_type();
236     action_array[i].value.choice.RICaction_ToBeSetup_Item.ricSubsequentAction->ricSubsequentActionType = (*ref_action_array)[i].get_subsequent_action();
237     
238     result = ASN_SEQUENCE_ADD(&ricsubscription_ie->ricAction_ToBeSetup_List, &(action_array[i]));
239     if (result == -1){
240       error_string = "Erorr : Unable to assign memory to add Action item to set up list";
241       return false;
242     }
243     
244   }
245   
246   result = ASN_SEQUENCE_ADD(&(ric_subscription->protocolIEs), &IE_array[ie_index]);
247   assert(result == 0);
248
249
250     
251   return true;
252 };
253
254
255
256 bool subscription_request:: get_fields(InitiatingMessage_t * init_msg,  subscription_helper & dout)
257 {
258
259   if (init_msg == 0){
260     error_string = "Error. Invalid reference when getting fields from subscription request";
261     return false;
262   }
263   
264   RICrequestID_t *requestid;
265   RANfunctionID_t * ranfunctionid;
266   RICsubscriptionDetails_t * ricsubscription;
267     
268   for(int edx = 0; edx < init_msg->value.choice.RICsubscriptionRequest.protocolIEs.list.count; edx++) {
269     RICsubscriptionRequest_IEs_t *memb_ptr = init_msg->value.choice.RICsubscriptionRequest.protocolIEs.list.array[edx];
270     
271     switch(memb_ptr->id)
272       {
273       case (ProtocolIE_ID_id_RICrequestID):
274         requestid = &memb_ptr->value.choice.RICrequestID;
275         //dout.set_request(requestid->ricRequestorID, requestid->ricRequestSequenceNumber);
276         break;
277           
278       case (ProtocolIE_ID_id_RANfunctionID):
279         ranfunctionid = &memb_ptr->value.choice.RANfunctionID;
280         dout.set_function_id(*ranfunctionid);
281         break;
282           
283       case (ProtocolIE_ID_id_RICsubscriptionDetails):
284         ricsubscription = &memb_ptr->value.choice.RICsubscriptionDetails;
285         dout.set_event_def(ricsubscription->ricEventTriggerDefinition.buf, ricsubscription->ricEventTriggerDefinition.size);
286           
287         for(int index = 0; index < ricsubscription->ricAction_ToBeSetup_List.list.count; index ++){
288           RICaction_ToBeSetup_ItemIEs_t * item = (RICaction_ToBeSetup_ItemIEs_t *)ricsubscription->ricAction_ToBeSetup_List.list.array[index];
289           if (item->value.choice.RICaction_ToBeSetup_Item.ricSubsequentAction == NULL){
290             dout.add_action(item->value.choice.RICaction_ToBeSetup_Item.ricActionID, item->value.choice.RICaction_ToBeSetup_Item.ricActionType);
291           }
292           else{
293             std::string action_def = ""; // for now we are ignoring action definition
294           }   
295         };
296         
297         break;
298       }
299       
300   }
301     
302   //asn_fprint(stdout, &asn_DEF_E2AP_PDU, e2pdu);
303   return true;
304 };
305
306
307