E2AP Abstraction Changes
[ric-app/hw.git] / src / xapp-asn / e2ap / e2ap_subscription_request.hpp
1 /*
2 ==================================================================================
3
4         Copyright (c) 2019-2020 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  * e2ap_subscription.hpp
21  *
22  *  Created on: Jun 30, 2020
23  *      Author: sjana
24  */
25
26 #ifndef XAPP_ASN_REFACTOR_E2AP_SUBSCRIPTION_HPP_
27 #define XAPP_ASN_REFACTOR_E2AP_SUBSCRIPTION_HPP_
28 #include <E2AP-PDU.h>
29 #include <InitiatingMessage.h>
30 #include <ProtocolIE-Field.h>
31 #include <RICsubscriptionRequest.h>
32 #include <ProtocolIE-SingleContainer.h>
33
34 #include <RICactions-ToBeSetup-List.h>
35 #include <RICsubsequentAction.h>
36 #include <vector>
37
38 #include "e2ap_action.hpp"
39 /*
40  RICsubscriptionRequest-IEs E2AP-PROTOCOL-IES ::= {
41         { ID id-RICrequestID                            CRITICALITY reject      TYPE RICrequestID                                       PRESENCE mandatory}|
42         { ID id-RANfunctionID                           CRITICALITY reject      TYPE RANfunctionID                                      PRESENCE mandatory}|
43         { ID id-RICsubscriptionDetails          CRITICALITY reject      TYPE RICsubscriptionDetails                     PRESENCE mandatory},
44         ...
45 }
46 RICrequestID ::= SEQUENCE {
47         ricRequestorID                          INTEGER (0..65535),
48         ricInstanceID   INTEGER (0..65535),
49         ...
50 }
51
52 RICsubscriptionDetails ::= SEQUENCE {
53         ricEventTriggerDefinition       RICeventTriggerDefinition,
54         ricAction-ToBeSetup-List        RICactions-ToBeSetup-List,
55         ...
56 }
57  */
58
59 template <typename E2SMEventTriggerDefinition, typename E2SMActionDefinition>
60 class E2APSubscriptionRequest {
61 public:
62
63         class SubscriptionRequestIEs{
64         private:
65                  long int ricRequestorID, ricInstanceID, ranFunctionID;
66                  size_t ricEventTriggerDefinition_size = E2SM_SIZE;
67                  unsigned char ricEventTriggerDefinition[E2SM_SIZE];
68
69                  int ricAction_ToBeSetup_List_Count;
70                  std::vector<typename E2APAction<E2SMActionDefinition>::ActionIEs> *ricAction_ToBeSetup_List;
71         public:
72                  SubscriptionRequestIEs(void):ricRequestorID(0), ricInstanceID(0), ranFunctionID(0), ricAction_ToBeSetup_List(0), ricAction_ToBeSetup_List_Count(0){};
73                  SubscriptionRequestIEs& set_ricRequestorID(long int req_id){ricRequestorID = req_id; return *this;};
74                  SubscriptionRequestIEs& set_ricInstanceID(long int inst_id){ricInstanceID = inst_id; return *this;};
75                  SubscriptionRequestIEs& set_ranFunctionID(long int func_id){ranFunctionID = func_id; return *this;};
76
77                  SubscriptionRequestIEs& set_ricEventTriggerDefinition(E2SMEventTriggerDefinition &eventObj)
78                  {
79                          bool res = eventObj.encode(&(this->ricEventTriggerDefinition)[0],&ricEventTriggerDefinition_size);
80                          if(!res){
81                                                 mdclog_write(MDCLOG_ERR, "Failed to encode: %s","RIC Event Trigger Definition");
82                                                 mdclog_write(MDCLOG_ERR, "Error during encode: %s",eventObj.get_error());
83                                         } else {
84                                                 mdclog_write(MDCLOG_INFO, "Successfully encoded: %s of size: %d","RIC Event Trigger Definition",ricEventTriggerDefinition_size);
85                                         }
86
87                     return *this;
88                  };
89
90                  SubscriptionRequestIEs& set_ricAction_ToBeSetup_List(E2APAction<E2SMActionDefinition>  &actionObj)
91                  { ricAction_ToBeSetup_List = actionObj.get_list();
92                    ricAction_ToBeSetup_List_Count = actionObj.get_list_count();
93                    return *this;
94                  };
95
96                  long int get_ricRequestorID(){return this->ricRequestorID;};
97                  long int get_ricInstanceID(){return this->ricInstanceID;};
98                  long int get_ranFunctionID(){return this->ranFunctionID;};
99
100                  unsigned char* get_ricEventTriggerDefinition(){return this->ricEventTriggerDefinition;};
101                  size_t get_ricEventTriggerDefinitionSize(){return this->ricEventTriggerDefinition_size;};
102                  std::vector<typename E2APAction<E2SMActionDefinition>::ActionIEs>* get_ricAction_ToBeSetup_List(){ return this->ricAction_ToBeSetup_List;};
103                  int get_ricAction_ToBeSetup_List_Count(){return this->ricAction_ToBeSetup_List_Count;};
104
105         };
106
107         E2APSubscriptionRequest(SubscriptionRequestIEs&);
108         ~E2APSubscriptionRequest();
109         bool encode(unsigned char *, size_t * );
110         std::string  get_error (void) const {return _error_string ;};
111         void add(SubscriptionRequestIEs &ies){_requestIEs = ies;};
112         SubscriptionRequestIEs& getIEs(){ return *_requestIEs.get();};
113 private:
114
115         unsigned int ricSubscriptionRequestIEs_Count;
116         InitiatingMessage_t *initMsg;
117         E2AP_PDU_t * e2ap_pdu_obj;
118         RICsubscriptionRequest_IEs_t * IE_array;
119         RICaction_ToBeSetup_ItemIEs_t * action_array;
120         unsigned int action_array_size;
121
122         std::unique_ptr<SubscriptionRequestIEs> _requestIEs;
123         std::string _error_string;
124     char _errbuf[128];
125         size_t _errbuf_len = 128;
126
127         bool setfields(InitiatingMessage_t *);
128 };
129
130 template <typename T1,typename T2>
131 E2APSubscriptionRequest<T1,T2>::E2APSubscriptionRequest(SubscriptionRequestIEs &subRequestObj){
132
133    ricSubscriptionRequestIEs_Count = 3;
134
135   _requestIEs = std::make_unique<SubscriptionRequestIEs>();
136   *_requestIEs = subRequestObj;
137
138   e2ap_pdu_obj = 0;
139   e2ap_pdu_obj = (E2AP_PDU_t * )calloc(1, sizeof(E2AP_PDU_t));
140   assert(e2ap_pdu_obj != 0);
141
142   initMsg = 0;
143   initMsg = (InitiatingMessage_t * )calloc(1, sizeof(InitiatingMessage_t));
144   assert(initMsg != 0);
145
146
147   IE_array = 0;
148   if(this->ricSubscriptionRequestIEs_Count == 0) {
149                   mdclog_write(MDCLOG_ERR, "E2AP Subscription Request IEs = 0.");
150   }
151   IE_array = (RICsubscriptionRequest_IEs_t *)calloc(this->ricSubscriptionRequestIEs_Count, sizeof(RICsubscriptionRequest_IEs_t));
152   assert(IE_array != 0);
153
154
155   action_array_size = subRequestObj.get_ricAction_ToBeSetup_List_Count();
156   action_array = 0;
157   action_array = (RICaction_ToBeSetup_ItemIEs_t *)calloc(action_array_size, sizeof(RICaction_ToBeSetup_ItemIEs_t));
158   assert(action_array != 0);
159
160
161   e2ap_pdu_obj->choice.initiatingMessage = initMsg;
162   e2ap_pdu_obj->present = E2AP_PDU_PR_initiatingMessage;
163
164
165
166 };
167
168 // Clear assigned protocolIE list from RIC indication IE container
169 template <typename T1, typename T2>
170 E2APSubscriptionRequest<T1,T2>::~E2APSubscriptionRequest(void){
171
172   mdclog_write(MDCLOG_DEBUG, "Freeing subscription request memory");;
173
174   RICsubscriptionDetails_t * ricsubscription_ie = &(IE_array[2].value.choice.RICsubscriptionDetails);
175
176   for(int i = 0; i < ricsubscription_ie->ricAction_ToBeSetup_List.list.size; i++){
177     ricsubscription_ie->ricAction_ToBeSetup_List.list.array[i] = 0;
178   }
179
180   // clear action list
181   if (ricsubscription_ie->ricAction_ToBeSetup_List.list.size > 0){
182     free(ricsubscription_ie->ricAction_ToBeSetup_List.list.array);
183     ricsubscription_ie->ricAction_ToBeSetup_List.list.size = 0;
184     ricsubscription_ie->ricAction_ToBeSetup_List.list.count = 0;
185     ricsubscription_ie->ricAction_ToBeSetup_List.list.array = 0;
186   }
187
188   // clear subsequent action array
189   for (unsigned int i = 0; i < action_array_size; i++){
190     free(action_array[i].value.choice.RICaction_ToBeSetup_Item.ricSubsequentAction );
191   }
192
193   free(action_array);
194   RICsubscriptionRequest_t * subscription_request = &(initMsg->value.choice.RICsubscriptionRequest);
195
196   for(int i = 0; i < subscription_request->protocolIEs.list.size; i++){
197     subscription_request->protocolIEs.list.array[i] = 0;
198   }
199
200   if( subscription_request->protocolIEs.list.size > 0){
201     free( subscription_request->protocolIEs.list.array);
202     subscription_request->protocolIEs.list.array = 0;
203     subscription_request->protocolIEs.list.size = 0;
204     subscription_request->protocolIEs.list.count = 0;
205   }
206
207   free(IE_array);
208   free(initMsg);
209   e2ap_pdu_obj->choice.initiatingMessage = 0;
210
211   ASN_STRUCT_FREE(asn_DEF_E2AP_PDU, e2ap_pdu_obj);
212   mdclog_write(MDCLOG_DEBUG, "Freed subscription request memory ");
213 };
214
215 template <typename T1, typename T2>
216 bool E2APSubscriptionRequest<T1,T2>::encode(unsigned char *buf, size_t *size){
217
218   bool res;
219
220   initMsg->procedureCode = ProcedureCode_id_RICsubscription;
221   initMsg->criticality = Criticality_ignore;
222   initMsg->value.present = InitiatingMessage__value_PR_RICsubscriptionRequest;
223
224   res = setfields(initMsg);
225   if (!res){
226     return false;
227   }
228
229   int ret_constr = asn_check_constraints(&asn_DEF_E2AP_PDU, (void *) e2ap_pdu_obj, _errbuf, &_errbuf_len);
230   if(ret_constr){
231     _error_string.assign(_errbuf, _errbuf_len);
232     _error_string = "Constraints failed for encoding subscription request. Reason = " + _error_string;
233     return false;
234   }
235
236   xer_fprint(stdout, &asn_DEF_E2AP_PDU, e2ap_pdu_obj);
237
238   asn_enc_rval_t retval = asn_encode_to_buffer(0, ATS_ALIGNED_BASIC_PER, &asn_DEF_E2AP_PDU, e2ap_pdu_obj, buf, *size);
239
240   if(retval.encoded == -1){
241     _error_string.assign(strerror(errno));
242     _error_string = "Error encoding Subscription  Request. Reason = " + _error_string;
243     return false;
244   }
245   else {
246     if(*size < retval.encoded){
247       std::stringstream ss;
248       ss  <<"Error encoding Subscription  Request . Reason =  encoded pdu size " << retval.encoded << " exceeds buffer size " << *size << std::endl;
249       _error_string = ss.str();
250       retval.encoded = -1;
251       return false;
252     }
253   }
254
255   *size = retval.encoded;
256   return true;
257
258 }
259
260 template <typename T1, typename T2>
261 bool E2APSubscriptionRequest<T1,T2>::setfields( InitiatingMessage_t * init_msg){
262
263
264   int ie_index;
265   int result = 0;
266
267   if (init_msg == 0){
268     _error_string = "Error. Invalid reference when getting fields from subscription request";
269     return false;
270   }
271
272   RICsubscriptionRequest_t * ric_subscription = &(init_msg->value.choice.RICsubscriptionRequest);
273   ric_subscription->protocolIEs.list.count = 0;
274
275   ie_index = 0;
276   RICsubscriptionRequest_IEs_t *ies_ricreq = &IE_array[ie_index];
277   ies_ricreq->criticality = Criticality_reject;
278   ies_ricreq->id = ProtocolIE_ID_id_RICrequestID;
279   ies_ricreq->value.present = RICsubscriptionRequest_IEs__value_PR_RICrequestID;
280   RICrequestID_t *ricrequest_ie = &ies_ricreq->value.choice.RICrequestID;
281   ricrequest_ie->ricRequestorID = this->getIEs().get_ricRequestorID();
282   result = ASN_SEQUENCE_ADD(&(ric_subscription->protocolIEs), &IE_array[ie_index]);
283           assert(result == 0);
284
285   ie_index = 1;
286   RICsubscriptionRequest_IEs_t *ies_ranfunc = &IE_array[ie_index];
287   ies_ranfunc->criticality = Criticality_reject;
288   ies_ranfunc->id = ProtocolIE_ID_id_RANfunctionID;
289   ies_ranfunc->value.present = RICsubscriptionRequest_IEs__value_PR_RANfunctionID;
290   RANfunctionID_t *ranfunction_ie = &ies_ranfunc->value.choice.RANfunctionID;
291   *ranfunction_ie = this->getIEs().get_ranFunctionID();
292   result = ASN_SEQUENCE_ADD(&(ric_subscription->protocolIEs), &IE_array[ie_index]);
293   assert(result == 0);
294
295
296   ie_index = 2;
297   RICsubscriptionRequest_IEs_t *ies_actid = &IE_array[ie_index];
298   ies_actid->criticality = Criticality_reject;
299   ies_actid->id = ProtocolIE_ID_id_RICsubscriptionDetails;
300   ies_actid->value.present = RICsubscriptionRequest_IEs__value_PR_RICsubscriptionDetails;
301
302   RICsubscriptionDetails_t *ricsubscription_ie = &ies_actid->value.choice.RICsubscriptionDetails;
303   ricsubscription_ie->ricEventTriggerDefinition.buf = (uint8_t *) this->getIEs().get_ricEventTriggerDefinition();
304   ricsubscription_ie->ricEventTriggerDefinition.size = this->getIEs().get_ricEventTriggerDefinitionSize();
305
306
307
308   std::vector<typename E2APAction<T2>::ActionIEs> *ref_action_array = this->getIEs().get_ricAction_ToBeSetup_List();
309
310   // reset the list count on ricAction_ToBeSetup_List;
311   ricsubscription_ie->ricAction_ToBeSetup_List.list.count = 0;
312
313   for(unsigned int i = 0; i < ref_action_array->size(); i ++){
314     action_array[i].criticality = Criticality_ignore;
315     action_array[i].id = ProtocolIE_ID_id_RICaction_ToBeSetup_Item ;
316     action_array[i].value.present = RICaction_ToBeSetup_ItemIEs__value_PR_RICaction_ToBeSetup_Item;
317
318     action_array[i].value.choice.RICaction_ToBeSetup_Item.ricActionID = (*ref_action_array)[i].get_ricActionID();
319     action_array[i].value.choice.RICaction_ToBeSetup_Item.ricActionType = (*ref_action_array)[i].get_ricActionType();
320
321     if((*ref_action_array)[i].get_is_ricSubsequentAction()){
322         action_array[i].value.choice.RICaction_ToBeSetup_Item.ricSubsequentAction = (RICsubsequentAction_t *)calloc(1, sizeof(RICsubsequentAction_t));
323         action_array[i].value.choice.RICaction_ToBeSetup_Item.ricSubsequentAction->ricSubsequentActionType = (*ref_action_array)[i].get_ricSubsequentActionType();
324         action_array[i].value.choice.RICaction_ToBeSetup_Item.ricSubsequentAction->ricTimeToWait = (*ref_action_array)[i].get_ricTimeToWait();
325     }
326     action_array[i].value.choice.RICaction_ToBeSetup_Item.ricActionDefinition = (RICactionDefinition_t*)calloc(1, sizeof(RICactionDefinition_t));
327
328     auto actionSize =  (*ref_action_array)[i].get_ricActionDefinition_size();
329     action_array[i].value.choice.RICaction_ToBeSetup_Item.ricActionDefinition->size = actionSize;
330     action_array[i].value.choice.RICaction_ToBeSetup_Item.ricActionDefinition->buf = (uint8_t *)calloc(1,actionSize);
331     memcpy(action_array[i].value.choice.RICaction_ToBeSetup_Item.ricActionDefinition->buf, (uint8_t*)(*ref_action_array)[i].get_ricActionDefinition(), actionSize);
332
333     action_array[i].value.choice.RICaction_ToBeSetup_Item.ricActionDefinition->size = actionSize;
334
335
336     result = ASN_SEQUENCE_ADD(&ricsubscription_ie->ricAction_ToBeSetup_List, &(action_array[i]));
337     if (result == -1){
338       _error_string = "Error : Unable to assign memory to add Action item to set up list";
339       return false;
340     }
341
342   }
343
344   result = ASN_SEQUENCE_ADD(&(ric_subscription->protocolIEs), &IE_array[ie_index]);
345   assert(result == 0);
346
347
348
349   return true;
350 };
351
352
353 #endif /* XAPP_ASN_REFACTOR_E2AP_SUBSCRIPTION_HPP_ */