0f2836de8c8cb77d95f82262c9b47716408bc2c7
[ric-app/admin.git] / src / E2AP-c / subscription / subscription_request.cc
1
2
3 /*
4 ==================================================================================
5         Copyright (c) 2018-2019 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 subscription_request::subscription_request(void){
25
26   _name = "default";
27
28   e2ap_pdu_obj = 0;
29   e2ap_pdu_obj = (E2N_E2AP_PDU_t * )calloc(1, sizeof(E2N_E2AP_PDU_t));
30   assert(e2ap_pdu_obj != 0);
31
32   initMsg = 0;
33   initMsg = (E2N_InitiatingMessage_t * )calloc(1, sizeof(E2N_InitiatingMessage_t));
34   assert(initMsg != 0);
35
36   IE_array = 0;
37   IE_array = (E2N_RICsubscriptionRequest_IEs_t *)calloc(NUM_SUBSCRIPTION_REQUEST_IES, sizeof(E2N_RICsubscriptionRequest_IEs_t));
38   assert(IE_array != 0);
39   
40   action_array = 0;
41   action_array = (E2N_RICaction_ToBeSetup_ItemIEs_t *)calloc(INITIAL_REQUEST_LIST_SIZE, sizeof(E2N_RICaction_ToBeSetup_ItemIEs_t));
42   assert(action_array != 0);
43   action_array_size = INITIAL_REQUEST_LIST_SIZE;
44   // also need to add subsequent action and time to wait ..
45   for (unsigned int i = 0; i < action_array_size; i++){
46     action_array[i].value.choice.RICaction_ToBeSetup_Item.ricSubsequentAction = (struct E2N_RICsubsequentAction *)calloc(1, sizeof(struct E2N_RICsubsequentAction));
47     assert(action_array[i].value.choice.RICaction_ToBeSetup_Item.ricSubsequentAction  != 0);
48   }
49   
50   e2ap_pdu_obj->choice.initiatingMessage = initMsg;
51   e2ap_pdu_obj->present = E2N_E2AP_PDU_PR_initiatingMessage;
52
53
54   
55 };
56
57
58
59 // Clear assigned protocolIE list from RIC indication IE container
60 subscription_request::~subscription_request(void){
61     
62   mdclog_write(MDCLOG_DEBUG, "Freeing subscription request memory for");;
63   
64   // Sequence of actions to be admitted causes special heart-ache. Free ric subscription element manually and reset the ie pointer  
65   E2N_RICsubscription_t * ricsubscription_ie = &(IE_array[2].value.choice.RICsubscription);
66
67   for(int i = 0; i < ricsubscription_ie->ricAction_ToBeSetup_List.list.size; i++){
68     ricsubscription_ie->ricAction_ToBeSetup_List.list.array[i] = 0;
69   }
70
71   if (ricsubscription_ie->ricAction_ToBeSetup_List.list.size > 0){
72     free(ricsubscription_ie->ricAction_ToBeSetup_List.list.array);
73     ricsubscription_ie->ricAction_ToBeSetup_List.list.size = 0;
74     ricsubscription_ie->ricAction_ToBeSetup_List.list.count = 0;
75     ricsubscription_ie->ricAction_ToBeSetup_List.list.array = 0;
76   }
77
78   // clear subsequent action array
79   for (unsigned int i = 0; i < action_array_size; i++){
80     free(action_array[i].value.choice.RICaction_ToBeSetup_Item.ricSubsequentAction );
81   }
82   
83   free(action_array);
84   E2N_RICsubscriptionRequest_t * subscription_request = &(initMsg->value.choice.RICsubscriptionRequest);
85   
86   for(int i = 0; i < subscription_request->protocolIEs.list.size; i++){
87     subscription_request->protocolIEs.list.array[i] = 0;
88   }
89   
90   if( subscription_request->protocolIEs.list.size > 0){
91     free( subscription_request->protocolIEs.list.array);
92     subscription_request->protocolIEs.list.array = 0;
93     subscription_request->protocolIEs.list.size = 0;
94     subscription_request->protocolIEs.list.count = 0;
95   }
96   
97   free(IE_array);
98   free(initMsg);
99   e2ap_pdu_obj->choice.initiatingMessage = 0;
100   
101   ASN_STRUCT_FREE(asn_DEF_E2N_E2AP_PDU, e2ap_pdu_obj);
102   mdclog_write(MDCLOG_DEBUG, "Freed subscription request memory ");
103 };
104
105
106 bool subscription_request::encode_e2ap_subscription(unsigned char *buf, size_t *size,  subscription_helper &dinput){
107
108   bool res;
109
110   initMsg->procedureCode = E2N_ProcedureCode_id_ricSubscription;
111   initMsg->criticality = E2N_Criticality_ignore;
112   initMsg->value.present = E2N_InitiatingMessage__value_PR_RICsubscriptionRequest;
113
114   res = set_fields(initMsg, dinput);
115   if (!res){
116     return false;
117   }
118   
119   int ret_constr = asn_check_constraints(&asn_DEF_E2N_E2AP_PDU, (void *) e2ap_pdu_obj, errbuf, &errbuf_len);
120   if(ret_constr){
121     error_string.assign(errbuf, errbuf_len);
122     error_string = "Constraints failed for encoding subscription request. Reason = " + error_string;
123     return false;
124   }
125
126   //xer_fprint(stdout, &asn_DEF_E2N_E2AP_PDU, e2ap_pdu_obj);
127   
128   asn_enc_rval_t retval = asn_encode_to_buffer(0, ATS_ALIGNED_BASIC_PER, &asn_DEF_E2N_E2AP_PDU, e2ap_pdu_obj, buf, *size);
129     
130   if(retval.encoded == -1){
131     error_string.assign(strerror(errno));
132     error_string = "Error encoding Subscription  Request. Reason = " + error_string;
133     return false;
134   }
135   else {
136     if(*size < retval.encoded){
137       std::stringstream ss;
138       ss  <<"Error encoding Subscription  Request . Reason =  encoded pdu size " << retval.encoded << " exceeds buffer size " << *size << std::endl;
139       error_string = ss.str();
140       retval.encoded = -1;
141       return false;
142     }
143   }
144     
145   *size = retval.encoded;
146   return true;
147     
148 }
149
150
151 bool subscription_request::set_fields( E2N_InitiatingMessage_t * init_msg, subscription_helper &helper){
152
153   
154   int ie_index;
155   int result = 0;
156
157   if (init_msg == 0){
158     error_string = "Error. Invalid reference when getting fields from subscription request";
159     return false;
160   }
161
162   E2N_RICsubscriptionRequest_t * ric_subscription = &(init_msg->value.choice.RICsubscriptionRequest);
163   ric_subscription->protocolIEs.list.count = 0;
164   
165   ie_index = 0;
166   E2N_RICsubscriptionRequest_IEs_t *ies_ricreq = &IE_array[ie_index];
167   ies_ricreq->criticality = E2N_Criticality_reject;
168   ies_ricreq->id = E2N_ProtocolIE_ID_id_RICrequestID;
169   ies_ricreq->value.present = E2N_RICsubscriptionRequest_IEs__value_PR_RICrequestID;
170   E2N_RICrequestID_t *ricrequest_ie = &ies_ricreq->value.choice.RICrequestID;
171   ricrequest_ie->ricRequestorID = helper.get_request_id();
172   ricrequest_ie->ricRequestSequenceNumber = helper.get_req_seq();
173   result = ASN_SEQUENCE_ADD(&(ric_subscription->protocolIEs), &IE_array[ie_index]);
174   assert(result == 0);
175      
176   ie_index = 1;
177   E2N_RICsubscriptionRequest_IEs_t *ies_ranfunc = &IE_array[ie_index];
178   ies_ranfunc->criticality = E2N_Criticality_reject;
179   ies_ranfunc->id = E2N_ProtocolIE_ID_id_RANfunctionID;
180   ies_ranfunc->value.present = E2N_RICsubscriptionRequest_IEs__value_PR_RANfunctionID;
181   E2N_RANfunctionID_t *ranfunction_ie = &ies_ranfunc->value.choice.RANfunctionID;
182   *ranfunction_ie = helper.get_function_id();
183   result = ASN_SEQUENCE_ADD(&(ric_subscription->protocolIEs), &IE_array[ie_index]);
184   assert(result == 0);
185
186
187   ie_index = 2;
188   E2N_RICsubscriptionRequest_IEs_t *ies_actid = &IE_array[ie_index];
189   ies_actid->criticality = E2N_Criticality_reject;
190   ies_actid->id = E2N_ProtocolIE_ID_id_RICsubscription;
191   ies_actid->value.present = E2N_RICsubscriptionRequest_IEs__value_PR_RICsubscription;
192   E2N_RICsubscription_t *ricsubscription_ie = &ies_actid->value.choice.RICsubscription;
193
194   ricsubscription_ie->ricEventTriggerDefinition.buf = (uint8_t *) helper.get_event_def();
195   ricsubscription_ie->ricEventTriggerDefinition.size = helper.get_event_def_size();
196    
197   std::vector<Action> * ref_action_array = helper.get_list();
198   // do we need to resize  ?
199   // we don't care about contents, so just do a free/calloc
200   if(action_array_size < ref_action_array->size()){
201     std::cout <<"re-allocating action array from " << action_array_size << " to " << 2 * ref_action_array->size() <<  std::endl;
202     // free subsequent allocation
203     for (unsigned int i = 0; i < action_array_size; i++){
204       free(action_array[i].value.choice.RICaction_ToBeSetup_Item.ricSubsequentAction );
205     }
206     
207     action_array_size = 2 * ref_action_array->size();
208     free(action_array);
209     action_array = (E2N_RICaction_ToBeSetup_ItemIEs_t *)calloc(action_array_size, sizeof(E2N_RICaction_ToBeSetup_ItemIEs_t));
210     assert(action_array != 0);
211
212     // also need to add subsequent action and time to wait ..
213     for (unsigned int i = 0; i < action_array_size; i++){
214       action_array[i].value.choice.RICaction_ToBeSetup_Item.ricSubsequentAction = (struct E2N_RICsubsequentAction *)calloc(1, sizeof(struct E2N_RICsubsequentAction));
215       assert(action_array[i].value.choice.RICaction_ToBeSetup_Item.ricSubsequentAction  != 0);
216     }
217     
218   }
219   
220   // reset the list count on ricAction_ToBeSetup_List;
221   ricsubscription_ie->ricAction_ToBeSetup_List.list.count = 0;
222   
223   for(unsigned int i = 0; i < ref_action_array->size(); i ++){
224     action_array[i].criticality = E2N_Criticality_ignore;
225     action_array[i].id = E2N_ProtocolIE_ID_id_RICaction_ToBeSetup_Item ;
226     action_array[i].value.present = E2N_RICaction_ToBeSetup_ItemIEs__value_PR_RICaction_ToBeSetup_Item;
227     action_array[i].value.choice.RICaction_ToBeSetup_Item.ricActionID = (*ref_action_array)[i].get_id();
228     action_array[i].value.choice.RICaction_ToBeSetup_Item.ricActionType = (*ref_action_array)[i].get_type();
229     action_array[i].value.choice.RICaction_ToBeSetup_Item.ricSubsequentAction->ricSubsequentActionType = (*ref_action_array)[i].get_subsequent_action();
230     action_array[i].value.choice.RICaction_ToBeSetup_Item.ricSubsequentAction->ricTimeToWait = (*ref_action_array)[i].get_wait();
231     
232     result = ASN_SEQUENCE_ADD(&ricsubscription_ie->ricAction_ToBeSetup_List, &(action_array[i]));
233     if (result == -1){
234       error_string = "Erorr : Unable to assign memory to add Action item to set up list";
235       return false;
236     }
237     
238   }
239   
240   result = ASN_SEQUENCE_ADD(&(ric_subscription->protocolIEs), &IE_array[ie_index]);
241   assert(result == 0);
242
243
244     
245   return true;
246 };
247
248
249
250 bool subscription_request:: get_fields(E2N_InitiatingMessage_t * init_msg,  subscription_helper & dout)
251 {
252
253   if (init_msg == 0){
254     error_string = "Error. Invalid reference when getting fields from subscription request";
255     return false;
256   }
257   
258   E2N_RICrequestID_t *requestid;
259   E2N_RANfunctionID_t * ranfunctionid;
260   E2N_RICsubscription_t * ricsubscription;
261     
262   for(int edx = 0; edx < init_msg->value.choice.RICsubscriptionRequest.protocolIEs.list.count; edx++) {
263     E2N_RICsubscriptionRequest_IEs_t *memb_ptr = init_msg->value.choice.RICsubscriptionRequest.protocolIEs.list.array[edx];
264     
265     switch(memb_ptr->id)
266       {
267       case (E2N_ProtocolIE_ID_id_RICrequestID):
268         requestid = &memb_ptr->value.choice.RICrequestID;
269         dout.set_request(requestid->ricRequestorID, requestid->ricRequestSequenceNumber);
270         break;
271           
272       case (E2N_ProtocolIE_ID_id_RANfunctionID):
273         ranfunctionid = &memb_ptr->value.choice.RANfunctionID;
274         dout.set_function_id(*ranfunctionid);
275         break;
276           
277       case (E2N_ProtocolIE_ID_id_RICsubscription):
278         ricsubscription = &memb_ptr->value.choice.RICsubscription;
279         dout.set_event_def(ricsubscription->ricEventTriggerDefinition.buf, ricsubscription->ricEventTriggerDefinition.size);
280           
281         for(int index = 0; index < ricsubscription->ricAction_ToBeSetup_List.list.count; index ++){
282           E2N_RICaction_ToBeSetup_ItemIEs_t * item = (E2N_RICaction_ToBeSetup_ItemIEs_t *)ricsubscription->ricAction_ToBeSetup_List.list.array[index];
283           if (item->value.choice.RICaction_ToBeSetup_Item.ricSubsequentAction == NULL){
284             dout.add_action(item->value.choice.RICaction_ToBeSetup_Item.ricActionID, item->value.choice.RICaction_ToBeSetup_Item.ricActionType);
285           }
286           else{
287             std::string action_def = ""; // for now we are ignoring action definition
288             dout.add_action(item->value.choice.RICaction_ToBeSetup_Item.ricActionID, item->value.choice.RICaction_ToBeSetup_Item.ricActionType, action_def, item->value.choice.RICaction_ToBeSetup_Item.ricSubsequentAction->ricSubsequentActionType, item->value.choice.RICaction_ToBeSetup_Item.ricSubsequentAction->ricTimeToWait);
289           }   
290         };
291         
292         break;
293       }
294       
295   }
296     
297   //asn_fprint(stdout, &asn_DEF_E2N_E2AP_PDU, e2pdu);
298   return true;
299 };
300
301
302