Control Message Encode/Decode
[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_request.hpp
21  *
22  *  Created on: Jun 30, 2020
23  *      Author: Shraboni Jana
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 = IE_SIZE;
67                  unsigned char ricEventTriggerDefinition[IE_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         InitiatingMessage_t *initMsg;
116         E2AP_PDU_t * e2ap_pdu_obj;
117         RICsubscriptionRequest_IEs_t * IE_array;
118         RICaction_ToBeSetup_ItemIEs_t * action_array;
119         unsigned int action_array_size;
120
121         std::unique_ptr<SubscriptionRequestIEs> _requestIEs;
122         std::string _error_string;
123     char _errbuf[128];
124         size_t _errbuf_len = 128;
125
126         bool setfields(InitiatingMessage_t *);
127 };
128
129 template <typename T1,typename T2>
130 E2APSubscriptionRequest<T1,T2>::E2APSubscriptionRequest(SubscriptionRequestIEs &subRequestObj){
131
132   _requestIEs = std::make_unique<SubscriptionRequestIEs>();
133   *_requestIEs = subRequestObj;
134
135   e2ap_pdu_obj = 0;
136   e2ap_pdu_obj = (E2AP_PDU_t * )calloc(1, sizeof(E2AP_PDU_t));
137   assert(e2ap_pdu_obj != 0);
138
139   initMsg = 0;
140   initMsg = (InitiatingMessage_t * )calloc(1, sizeof(InitiatingMessage_t));
141   assert(initMsg != 0);
142
143
144   IE_array = 0;
145   if(RIC_SUB_REQUEST_IES_COUNT == 0) {
146                   mdclog_write(MDCLOG_ERR, "E2AP Subscription Request IEs = 0.");
147   }
148   IE_array = (RICsubscriptionRequest_IEs_t *)calloc(RIC_SUB_REQUEST_IES_COUNT, sizeof(RICsubscriptionRequest_IEs_t));
149   assert(IE_array != 0);
150
151
152   action_array_size = subRequestObj.get_ricAction_ToBeSetup_List_Count();
153   action_array = 0;
154   action_array = (RICaction_ToBeSetup_ItemIEs_t *)calloc(action_array_size, sizeof(RICaction_ToBeSetup_ItemIEs_t));
155   assert(action_array != 0);
156
157
158   e2ap_pdu_obj->choice.initiatingMessage = initMsg;
159   e2ap_pdu_obj->present = E2AP_PDU_PR_initiatingMessage;
160
161
162
163 };
164
165 // Clear assigned protocolIE list from RIC indication IE container
166 template <typename T1, typename T2>
167 E2APSubscriptionRequest<T1,T2>::~E2APSubscriptionRequest(void){
168
169   mdclog_write(MDCLOG_DEBUG, "Freeing subscription request memory");;
170
171   RICsubscriptionDetails_t * ricsubscription_ie = &(IE_array[2].value.choice.RICsubscriptionDetails);
172
173   for(int i = 0; i < ricsubscription_ie->ricAction_ToBeSetup_List.list.size; i++){
174     ricsubscription_ie->ricAction_ToBeSetup_List.list.array[i] = 0;
175   }
176
177   // clear action list
178   if (ricsubscription_ie->ricAction_ToBeSetup_List.list.size > 0){
179     free(ricsubscription_ie->ricAction_ToBeSetup_List.list.array);
180     ricsubscription_ie->ricAction_ToBeSetup_List.list.size = 0;
181     ricsubscription_ie->ricAction_ToBeSetup_List.list.count = 0;
182     ricsubscription_ie->ricAction_ToBeSetup_List.list.array = 0;
183   }
184
185   // clear subsequent action array
186   for (unsigned int i = 0; i < action_array_size; i++){
187     free(action_array[i].value.choice.RICaction_ToBeSetup_Item.ricSubsequentAction );
188   }
189
190   free(action_array);
191   RICsubscriptionRequest_t * subscription_request = &(initMsg->value.choice.RICsubscriptionRequest);
192
193   for(int i = 0; i < subscription_request->protocolIEs.list.size; i++){
194     subscription_request->protocolIEs.list.array[i] = 0;
195   }
196
197   if( subscription_request->protocolIEs.list.size > 0){
198     free( subscription_request->protocolIEs.list.array);
199     subscription_request->protocolIEs.list.array = 0;
200     subscription_request->protocolIEs.list.size = 0;
201     subscription_request->protocolIEs.list.count = 0;
202   }
203
204   free(IE_array);
205   free(initMsg);
206   e2ap_pdu_obj->choice.initiatingMessage = 0;
207
208   ASN_STRUCT_FREE(asn_DEF_E2AP_PDU, e2ap_pdu_obj);
209   mdclog_write(MDCLOG_DEBUG, "Freed subscription request memory ");
210 };
211
212 template <typename T1, typename T2>
213 bool E2APSubscriptionRequest<T1,T2>::encode(unsigned char *buf, size_t *size){
214
215   bool res;
216
217   initMsg->procedureCode = ProcedureCode_id_RICsubscription;
218   initMsg->criticality = Criticality_ignore;
219   initMsg->value.present = InitiatingMessage__value_PR_RICsubscriptionRequest;
220
221   res = setfields(initMsg);
222   if (!res){
223     return false;
224   }
225
226   int ret_constr = asn_check_constraints(&asn_DEF_E2AP_PDU, (void *) e2ap_pdu_obj, _errbuf, &_errbuf_len);
227   if(ret_constr){
228     _error_string.assign(_errbuf, _errbuf_len);
229     _error_string = "Constraints failed for encoding subscription request. Reason = " + _error_string;
230     return false;
231   }
232
233   xer_fprint(stdout, &asn_DEF_E2AP_PDU, e2ap_pdu_obj);
234
235   asn_enc_rval_t retval = asn_encode_to_buffer(0, ATS_ALIGNED_BASIC_PER, &asn_DEF_E2AP_PDU, e2ap_pdu_obj, buf, *size);
236
237   if(retval.encoded == -1){
238     _error_string.assign(strerror(errno));
239     _error_string = "Error encoding Subscription  Request. Reason = " + _error_string;
240     return false;
241   }
242   else {
243     if(*size < retval.encoded){
244       std::stringstream ss;
245       ss  <<"Error encoding Subscription  Request . Reason =  encoded pdu size " << retval.encoded << " exceeds buffer size " << *size << std::endl;
246       _error_string = ss.str();
247       retval.encoded = -1;
248       return false;
249     }
250   }
251
252   *size = retval.encoded;
253   return true;
254
255 }
256
257 template <typename T1, typename T2>
258 bool E2APSubscriptionRequest<T1,T2>::setfields( InitiatingMessage_t * init_msg){
259
260
261   int ie_index;
262   int result = 0;
263
264   if (init_msg == 0){
265     _error_string = "Error. Invalid reference when getting fields from subscription request";
266     return false;
267   }
268
269   RICsubscriptionRequest_t * ric_subscription = &(init_msg->value.choice.RICsubscriptionRequest);
270   ric_subscription->protocolIEs.list.count = 0;
271
272   ie_index = 0;
273   RICsubscriptionRequest_IEs_t *ies_ricreq = &IE_array[ie_index];
274   ies_ricreq->criticality = Criticality_reject;
275   ies_ricreq->id = ProtocolIE_ID_id_RICrequestID;
276   ies_ricreq->value.present = RICsubscriptionRequest_IEs__value_PR_RICrequestID;
277   RICrequestID_t *ricrequest_ie = &ies_ricreq->value.choice.RICrequestID;
278   ricrequest_ie->ricRequestorID = this->getIEs().get_ricRequestorID();
279   result = ASN_SEQUENCE_ADD(&(ric_subscription->protocolIEs), &IE_array[ie_index]);
280           assert(result == 0);
281
282   ie_index++;
283   RICsubscriptionRequest_IEs_t *ies_ranfunc = &IE_array[ie_index];
284   ies_ranfunc->criticality = Criticality_reject;
285   ies_ranfunc->id = ProtocolIE_ID_id_RANfunctionID;
286   ies_ranfunc->value.present = RICsubscriptionRequest_IEs__value_PR_RANfunctionID;
287   RANfunctionID_t *ranfunction_ie = &ies_ranfunc->value.choice.RANfunctionID;
288   *ranfunction_ie = this->getIEs().get_ranFunctionID();
289   result = ASN_SEQUENCE_ADD(&(ric_subscription->protocolIEs), &IE_array[ie_index]);
290   assert(result == 0);
291
292
293   ie_index++;
294   RICsubscriptionRequest_IEs_t *ies_actid = &IE_array[ie_index];
295   ies_actid->criticality = Criticality_reject;
296   ies_actid->id = ProtocolIE_ID_id_RICsubscriptionDetails;
297   ies_actid->value.present = RICsubscriptionRequest_IEs__value_PR_RICsubscriptionDetails;
298
299   RICsubscriptionDetails_t *ricsubscription_ie = &ies_actid->value.choice.RICsubscriptionDetails;
300   ricsubscription_ie->ricEventTriggerDefinition.buf = (uint8_t *) this->getIEs().get_ricEventTriggerDefinition();
301   ricsubscription_ie->ricEventTriggerDefinition.size = this->getIEs().get_ricEventTriggerDefinitionSize();
302
303
304
305   std::vector<typename E2APAction<T2>::ActionIEs> *ref_action_array = this->getIEs().get_ricAction_ToBeSetup_List();
306
307   // reset the list count on ricAction_ToBeSetup_List;
308   ricsubscription_ie->ricAction_ToBeSetup_List.list.count = 0;
309
310   for(unsigned int i = 0; i < ref_action_array->size(); i ++){
311     action_array[i].criticality = Criticality_ignore;
312     action_array[i].id = ProtocolIE_ID_id_RICaction_ToBeSetup_Item ;
313     action_array[i].value.present = RICaction_ToBeSetup_ItemIEs__value_PR_RICaction_ToBeSetup_Item;
314
315     action_array[i].value.choice.RICaction_ToBeSetup_Item.ricActionID = (*ref_action_array)[i].get_ricActionID();
316     action_array[i].value.choice.RICaction_ToBeSetup_Item.ricActionType = (*ref_action_array)[i].get_ricActionType();
317
318     if((*ref_action_array)[i].get_is_ricSubsequentAction()){
319         action_array[i].value.choice.RICaction_ToBeSetup_Item.ricSubsequentAction = (RICsubsequentAction_t *)calloc(1, sizeof(RICsubsequentAction_t));
320         action_array[i].value.choice.RICaction_ToBeSetup_Item.ricSubsequentAction->ricSubsequentActionType = (*ref_action_array)[i].get_ricSubsequentActionType();
321         action_array[i].value.choice.RICaction_ToBeSetup_Item.ricSubsequentAction->ricTimeToWait = (*ref_action_array)[i].get_ricTimeToWait();
322     }
323
324     if((*ref_action_array)[i].get_is_ricActionDefinition()){
325         action_array[i].value.choice.RICaction_ToBeSetup_Item.ricActionDefinition = (RICactionDefinition_t*)calloc(1, sizeof(RICactionDefinition_t));
326
327         auto actionSize =  (*ref_action_array)[i].get_ricActionDefinition_size();
328         action_array[i].value.choice.RICaction_ToBeSetup_Item.ricActionDefinition->size = actionSize;
329         action_array[i].value.choice.RICaction_ToBeSetup_Item.ricActionDefinition->buf = (uint8_t *)calloc(1,actionSize);
330         memcpy(action_array[i].value.choice.RICaction_ToBeSetup_Item.ricActionDefinition->buf, (uint8_t*)(*ref_action_array)[i].get_ricActionDefinition(), actionSize);
331
332         action_array[i].value.choice.RICaction_ToBeSetup_Item.ricActionDefinition->size = actionSize;
333     }
334
335     result = ASN_SEQUENCE_ADD(&ricsubscription_ie->ricAction_ToBeSetup_List, &(action_array[i]));
336     if (result == -1){
337       _error_string = "Error : Unable to assign memory to add Action item to set up list";
338       return false;
339     }
340
341   }
342
343   result = ASN_SEQUENCE_ADD(&(ric_subscription->protocolIEs), &IE_array[ie_index]);
344   assert(result == 0);
345
346
347
348   return true;
349 };
350
351
352 #endif /* XAPP_ASN_REFACTOR_E2AP_SUBSCRIPTION_HPP_ */