E2AP Wrapper Implementation
[ric-app/hw.git] / src / xapp-asn / e2ap / e2ap_indication.hpp
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  * e2ap_indication.hpp
23  *
24  *  Created on: Sep 18, 2020
25  *      Author: Shraboni Jana
26  */
27 /*-- **************************************************************
28 --
29 -- RIC Indication Elementary Procedure
30 --
31 -- **************************************************************
32 -- **************************************************************
33 --
34 -- RIC INDICATION
35 --
36 -- **************************************************************
37 RICindication ::= SEQUENCE {
38         protocolIEs                                     ProtocolIE-Container    {{RICindication-IEs}},
39         ...
40 }
41
42 RICindication-IEs E2AP-PROTOCOL-IES ::= {
43         { ID id-RICrequestID                            CRITICALITY reject      TYPE RICrequestID                                       PRESENCE mandatory      }|
44         { ID id-RANfunctionID                           CRITICALITY reject      TYPE RANfunctionID                                      PRESENCE mandatory      }|
45         { ID id-RICactionID                                     CRITICALITY reject      TYPE RICactionID                                        PRESENCE mandatory      }|
46         { ID id-RICindicationSN                         CRITICALITY reject      TYPE RICindicationSN                            PRESENCE optional       }|
47         { ID id-RICindicationType                       CRITICALITY reject      TYPE RICindicationType                          PRESENCE mandatory      }|
48         { ID id-RICindicationHeader                     CRITICALITY reject      TYPE RICindicationHeader                        PRESENCE mandatory      }|
49         { ID id-RICindicationMessage            CRITICALITY reject      TYPE RICindicationMessage                       PRESENCE mandatory      }|
50         { ID id-RICcallProcessID                        CRITICALITY reject      TYPE RICcallProcessID                           PRESENCE optional       },
51         ...
52 }*/
53
54
55 #ifndef SRC_XAPP_ASN_E2AP_E2AP_INDICATION_HPP_
56 #define SRC_XAPP_ASN_E2AP_E2AP_INDICATION_HPP_
57
58 #include <string>
59 #include <E2AP-PDU.h>
60 #include <InitiatingMessage.h>
61 #include <RICindication.h>
62 #include <ProtocolIE-Field.h>
63 #include <iostream>
64 #include <errno.h>
65 #include <mdclog/mdclog.h>
66 #include <sstream>
67 #include <memory>
68
69 #include "e2ap_consts.hpp"
70
71 template <typename E2SMIndicationHeader, typename E2SMIndicationMessage>
72 class E2APIndication{
73
74 public:
75
76         class IndicationIEs{
77                 private:
78                         long int ricRequestorID, ranFunctionID, ricActionID, ricIndicationSN, ricIndicationType;
79                         size_t ricIndicationHeader_size = IE_SIZE;
80                         unsigned char ricIndicationHeader[IE_SIZE];
81
82                         size_t ricIndicationMessage_size = IE_SIZE;
83                         unsigned char ricIndicationMessage[IE_SIZE];
84
85                         unsigned char ricCallProcessId[IE_SIZE];
86                         size_t ricCallProcessId_size = IE_SIZE;
87
88                         bool is_callProcessID, is_ricIndicationSN;
89
90                 public:
91                         IndicationIEs(void) : ricRequestorID(0), ranFunctionID(0), ricActionID(0),ricIndicationSN(0), ricIndicationType(0),is_callProcessID(false),is_ricIndicationSN(false){};
92                         void* get_ricIndicationMessage(){return this->ricIndicationMessage; };
93                         void* get_ricIndicationHeader(){return this->ricIndicationHeader; };
94                         void* get_ricCallProcessId(){return this->ricCallProcessId;};
95
96                         size_t get_ricIndicationMessage_size(){return this->ricIndicationMessage_size; };
97                         size_t get_ricIndicationHeader_size(){return this->ricIndicationHeader_size; };
98                         size_t get_ricCallProcessId_size(){return this->ricCallProcessId_size;};
99
100                         long int get_ricRequestorID(){return this->ricRequestorID;};
101                         long int get_ranFunctionID(){return this->ranFunctionID;};
102                         long int get_ricActionID(){return this->ricActionID;};
103                         long int get_ricIndicationType(){return this->ricIndicationType;}
104                         long int get_ricIndicationSN(){return this->ricIndicationSN;};
105                         bool get_is_ricIndicationSN(){return this->is_ricIndicationSN;};
106                         bool get_is_callProcessID(){return this->is_callProcessID;};
107
108                         IndicationIEs& set_ricIndicationHeader(E2SMIndicationHeader e2smObj){
109                                 bool res = e2smObj.encode(&(this->ricIndicationHeader)[0],&this->ricIndicationHeader_size);
110                                 if(!res){
111                                                 mdclog_write(MDCLOG_ERR, "Failed to encode: %s","RIC Indication Header");
112                                                 mdclog_write(MDCLOG_ERR, "Error during encode: %s",e2smObj.get_error());
113
114                                         } else {
115                                                  mdclog_write(MDCLOG_INFO, "Successfully encoded: %s","RIC Indication Header");
116                                 }
117                                         return *this;
118                         }
119                         IndicationIEs& set_ricIndicationMessage(E2SMIndicationMessage e2smObj){
120                                 bool res = e2smObj.encode(&(this->ricIndicationMessage)[0],&this->ricIndicationMessage_size);
121                                 if(!res){
122                                                         mdclog_write(MDCLOG_ERR, "Failed to encode: %s","RIC Indication Message");
123                                                         mdclog_write(MDCLOG_ERR, "Error during encode: %s",e2smObj.get_error());
124                                                 } else {
125                                                     mdclog_write(MDCLOG_INFO, "Successfully encoded: %s","RIC Indication Message");
126                                                 }
127
128                                 return *this;
129
130                         }
131
132                         IndicationIEs& set_ricIndicationHeader(unsigned char* header, size_t header_size){
133                                                         memcpy(ricIndicationHeader,header,header_size); ricIndicationHeader_size = header_size; return *this;
134                                                 }
135                         IndicationIEs& set_ricIndicationMessage(unsigned char* message, size_t message_size){
136                                                         memcpy(ricIndicationHeader,message,message_size); ricIndicationMessage_size = message_size; return *this;}
137
138                         IndicationIEs& set_ricCallProcessID(unsigned char* callproc, size_t callproc_size){
139                                 is_callProcessID = true;
140                                 memcpy(ricCallProcessId, callproc, callproc_size); ricCallProcessId_size = callproc_size;
141                                 return *this;
142                         }
143
144                         IndicationIEs& set_ricRequestorID(long int reqID){this->ricRequestorID = reqID; return *this;}
145                         IndicationIEs& set_ranFunctionID(long int funcID){this->ranFunctionID = funcID; return *this;}
146                         IndicationIEs& set_ricActionID(long int actID){ this->ricActionID = actID; return *this;}
147                         IndicationIEs& set_ricIndicationType(long int typ){ this->ricIndicationType = typ; return *this;}
148                         IndicationIEs& set_ricIndicationSN(long int sn){ this->ricIndicationSN = sn; is_ricIndicationSN=true; return *this;}
149
150
151         };
152
153    E2APIndication(IndicationIEs&);
154    E2APIndication(unsigned char *, size_t *);
155   ~E2APIndication(void);
156   IndicationIEs getIndicationIEs(){ return *_indicationIEs.get(); }
157
158   std::string get_error(void) const {return _error_string ; };
159   bool encode(unsigned char *buf, size_t *size);
160   bool decode(unsigned char *buf, size_t *size);
161
162 private:
163
164   E2AP_PDU_t * e2ap_pdu_obj;
165   InitiatingMessage_t *initMsg;
166   RICindication_IEs_t *IE_array;
167   std::unique_ptr<IndicationIEs> _indicationIEs;
168
169   std::string _error_string;
170   char _errbuf[128];
171   size_t _errbuf_len = 128;
172
173   bool setfields( InitiatingMessage_t *);
174 };
175
176 template<typename T1, typename T2>
177 E2APIndication<T1,T2>::E2APIndication(IndicationIEs& ieObj){
178
179   e2ap_pdu_obj = 0;
180   e2ap_pdu_obj = (E2AP_PDU_t * )calloc(1, sizeof(E2AP_PDU_t));
181   assert(e2ap_pdu_obj != 0);
182
183   initMsg = 0;
184   initMsg = (InitiatingMessage_t * )calloc(1, sizeof(InitiatingMessage_t));
185   assert(initMsg != 0);
186
187   IE_array = 0;
188   IE_array = (RICindication_IEs_t *)calloc(RIC_INDICATION_IES_COUNT, sizeof(RICindication_IEs_t));
189   assert(IE_array != 0);
190
191   e2ap_pdu_obj->present = E2AP_PDU_PR_initiatingMessage;
192   e2ap_pdu_obj->choice.initiatingMessage = initMsg;
193
194   _indicationIEs = std::make_unique<IndicationIEs>();
195   *_indicationIEs = ieObj;
196
197 };
198 template<typename T1, typename T2>
199 E2APIndication<T1,T2>::E2APIndication(unsigned char *buf, size_t *size){
200           e2ap_pdu_obj = 0;
201           initMsg = 0;
202           IE_array = 0;
203
204           _indicationIEs = std::make_unique<IndicationIEs>();
205            bool status =  this->decode(buf, size);
206            if(!status)
207                    throw "E2AP Indication Decode Failed: "+this->get_error();
208 }
209
210
211 // Clear assigned protocolIE list from RIC indication IE container
212 template<typename T1, typename T2>
213 E2APIndication<T1,T2>::~E2APIndication(void){
214
215   mdclog_write(MDCLOG_DEBUG, "Freeing E2AP Indication object memory");
216   RICindication_t *ricIndication  = &(initMsg->value.choice.RICindication);
217   for(int i = 0; i < ricIndication->protocolIEs.list.size; i++){
218     ricIndication->protocolIEs.list.array[i] = 0;
219   }
220   if (ricIndication->protocolIEs.list.size > 0){
221     free(ricIndication->protocolIEs.list.array);
222     ricIndication->protocolIEs.list.array = 0;
223     ricIndication->protocolIEs.list.count = 0;
224     ricIndication->protocolIEs.list.size = 0;
225   }
226
227   free(IE_array);
228   free(initMsg);
229   ASN_STRUCT_FREE(asn_DEF_E2AP_PDU, e2ap_pdu_obj);
230   mdclog_write(MDCLOG_DEBUG, "Freed E2AP Indication object memory");
231 }
232
233 template<typename T1, typename T2>
234 bool E2APIndication<T1, T2>::decode(unsigned char *buf, size_t *size)
235 {
236
237         asn_dec_rval_t dec_res  = asn_decode(0,ATS_ALIGNED_BASIC_PER, &asn_DEF_E2AP_PDU, (void**)&(e2ap_pdu_obj), buf, *size);
238         if(dec_res.code != RC_OK){
239                          mdclog_write(MDCLOG_ERR, "Failed to decode: %s","RIC Indication Message");
240                          return false;
241         } else {
242                          mdclog_write(MDCLOG_INFO, "Successfully decoded: %s","RIC Indication Message");
243         }
244
245   initMsg = e2ap_pdu_obj->choice.initiatingMessage;
246   //write the decoding code.
247   if (initMsg == 0){
248     _error_string = "Invalid reference for E2AP Indication message in get_fields";
249     return false;
250   }
251
252
253   for(int edx = 0; edx < initMsg->value.choice.RICindication.protocolIEs.list.count; edx++) {
254         RICindication_IEs_t *memb_ptr = initMsg->value.choice.RICindication.protocolIEs.list.array[edx];
255     switch(memb_ptr->id)
256      {
257       case (ProtocolIE_ID_id_RICindicationHeader):
258                 _indicationIEs->set_ricIndicationHeader(memb_ptr->value.choice.RICindicationHeader.buf, memb_ptr->value.choice.RICindicationHeader.size);
259       break;
260
261       case (ProtocolIE_ID_id_RICindicationMessage):
262                 _indicationIEs->set_ricIndicationMessage(memb_ptr->value.choice.RICindicationMessage.buf, memb_ptr->value.choice.RICindicationMessage.size);
263       break;
264
265       case (ProtocolIE_ID_id_RICrequestID):
266                 _indicationIEs->set_ricRequestorID(memb_ptr->value.choice.RICrequestID.ricRequestorID);
267       break;
268
269       case (ProtocolIE_ID_id_RANfunctionID):
270                 _indicationIEs->set_ranFunctionID(memb_ptr->value.choice.RANfunctionID);
271           break;
272
273       case (ProtocolIE_ID_id_RICindicationSN):
274                 _indicationIEs->set_ricIndicationSN(memb_ptr->value.choice.RICindicationSN);
275           break;
276
277       case (ProtocolIE_ID_id_RICindicationType):
278                 _indicationIEs->set_ricIndicationType(memb_ptr->value.choice.RICindicationType);
279           break;
280
281       case (ProtocolIE_ID_id_RICactionID):
282                 _indicationIEs->set_ricActionID(memb_ptr->value.choice.RICactionID);
283           break;
284
285       case (ProtocolIE_ID_id_RICcallProcessID):
286                 _indicationIEs->set_ricCallProcessID(memb_ptr->value.choice.RICcallProcessID.buf,memb_ptr->value.choice.RICcallProcessID.size);
287           break;
288
289       default:
290       break;
291       }
292
293   }
294   //  xer_fprint(stdout, &asn_DEF_E2AP_PDU, e2ap_pdu_obj);
295
296   return true;
297
298 }
299
300 template<typename T1, typename T2>
301 bool E2APIndication<T1,T2>::encode(unsigned char *buf, size_t *size){
302
303   initMsg->procedureCode = ProcedureCode_id_RICindication;
304   initMsg->criticality = Criticality_ignore;
305   initMsg->value.present = InitiatingMessage__value_PR_RICindication;
306
307   bool res;
308   asn_enc_rval_t retval;
309
310   res = setfields(initMsg);
311   if (!res){
312     return false;
313   }
314
315   int ret_constr = asn_check_constraints(&asn_DEF_E2AP_PDU, e2ap_pdu_obj, _errbuf, &_errbuf_len);
316   if(ret_constr){
317     _error_string.assign(&_errbuf[0], _errbuf_len);
318     _error_string = "Error encoding E2AP Indication message. Reason = " + _error_string;
319     return false;
320   }
321
322   retval = asn_encode_to_buffer(0, ATS_ALIGNED_BASIC_PER, &asn_DEF_E2AP_PDU, e2ap_pdu_obj, buf, *size);
323   if(retval.encoded == -1){
324     _error_string.assign(strerror(errno));
325     return false;
326   }
327
328   else {
329     if(*size < retval.encoded){
330       std::stringstream ss;
331       ss  <<"Error encoding E2AP Indication . Reason =  encoded pdu size " << retval.encoded << " exceeds buffer size " << *size << std::endl;
332       _error_string = ss.str();
333       return false;
334     }
335   }
336
337   *size = retval.encoded;
338   xer_fprint(stdout, &asn_DEF_E2AP_PDU, e2ap_pdu_obj);
339
340   return true;
341
342 }
343 template<typename T1, typename T2>
344 bool E2APIndication<T1,T2>::setfields(InitiatingMessage_t *initMsg){
345   unsigned int ie_index;
346
347   if (initMsg == 0){
348     _error_string = "Invalid reference for E2AP Indication message in set_fields";
349     return false;
350   }
351
352
353   RICindication_t * ric_indication = &(initMsg->value.choice.RICindication);
354   ric_indication->protocolIEs.list.count = 0;
355
356   ie_index = 0;
357
358   RICindication_IEs_t *ies_ricreq = &IE_array[ie_index];
359   ies_ricreq->criticality = Criticality_reject;
360   ies_ricreq->id = ProtocolIE_ID_id_RICrequestID;
361   ies_ricreq->value.present = RICindication_IEs__value_PR_RICrequestID;
362   RICrequestID_t *ricrequest_ie = &ies_ricreq->value.choice.RICrequestID;
363   ricrequest_ie->ricRequestorID = _indicationIEs->get_ricRequestorID();
364   ASN_SEQUENCE_ADD(&(ric_indication->protocolIEs), &(IE_array[ie_index]));
365
366   ie_index++;
367   RICindication_IEs_t *ies_ranfunc = &IE_array[ie_index];
368   ies_ranfunc->criticality = Criticality_reject;
369   ies_ranfunc->id = ProtocolIE_ID_id_RANfunctionID;
370   ies_ranfunc->value.present = RICindication_IEs__value_PR_RANfunctionID;
371   RANfunctionID_t *ranfunction_ie = &ies_ranfunc->value.choice.RANfunctionID;
372   *ranfunction_ie = _indicationIEs->get_ranFunctionID();
373   ASN_SEQUENCE_ADD(&(ric_indication->protocolIEs), &(IE_array[ie_index]));
374
375   ie_index++;
376   RICindication_IEs_t *ies_actid = &IE_array[ie_index];
377   ies_actid->criticality = Criticality_reject;
378   ies_actid->id = ProtocolIE_ID_id_RICactionID;
379   ies_actid->value.present = RICindication_IEs__value_PR_RICactionID;
380   RICactionID_t *ricaction_ie = &ies_actid->value.choice.RICactionID;
381   *ricaction_ie = _indicationIEs->get_ricActionID();
382   ASN_SEQUENCE_ADD(&(ric_indication->protocolIEs), &(IE_array[ie_index]));
383
384   if(_indicationIEs->get_is_ricIndicationSN())
385   {
386           ie_index++;
387           RICindication_IEs_t *ies_ricsn = &IE_array[ie_index];
388           ies_ricsn->criticality = Criticality_reject;
389           ies_ricsn->id = ProtocolIE_ID_id_RICindicationSN;
390           ies_ricsn->value.present = RICindication_IEs__value_PR_RICindicationSN;
391           RICindicationSN_t *ricsn_ie = &ies_ricsn->value.choice.RICindicationSN;
392           *ricsn_ie = _indicationIEs->get_ricIndicationSN();
393           ASN_SEQUENCE_ADD(&(ric_indication->protocolIEs), &(IE_array[ie_index]));
394   }
395
396   ie_index++;
397   RICindication_IEs_t *ies_indtyp = &IE_array[ie_index];
398   ies_indtyp->criticality = Criticality_reject;
399   ies_indtyp->id = ProtocolIE_ID_id_RICindicationType;
400   ies_indtyp->value.present = RICindication_IEs__value_PR_RICindicationType;
401   RICindicationType_t *rictype_ie = &ies_indtyp->value.choice.RICindicationType;
402   *rictype_ie = _indicationIEs->get_ricIndicationType();
403   ASN_SEQUENCE_ADD(&(ric_indication->protocolIEs), &(IE_array[ie_index]));
404
405   ie_index++;
406   RICindication_IEs_t *ies_richead = &IE_array[ie_index];
407   ies_richead->criticality = Criticality_reject;
408   ies_richead->id = ProtocolIE_ID_id_RICindicationHeader;
409   ies_richead->value.present = RICindication_IEs__value_PR_RICindicationHeader;
410   RICindicationHeader_t *richeader_ie = &ies_richead->value.choice.RICindicationHeader;
411   richeader_ie->buf = (uint8_t*)_indicationIEs->get_ricIndicationHeader();
412   richeader_ie->size = _indicationIEs->get_ricIndicationHeader_size();
413   ASN_SEQUENCE_ADD(&(ric_indication->protocolIEs), &(IE_array[ie_index]));
414
415   ie_index++;
416   RICindication_IEs_t *ies_indmsg = &IE_array[ie_index];
417   ies_indmsg->criticality = Criticality_reject;
418   ies_indmsg->id = ProtocolIE_ID_id_RICindicationMessage;
419   ies_indmsg->value.present = RICindication_IEs__value_PR_RICindicationMessage;
420   RICindicationMessage_t *ricmsg_ie = &ies_indmsg->value.choice.RICindicationMessage;
421   ricmsg_ie->buf = (uint8_t*)_indicationIEs->get_ricIndicationMessage();
422   ricmsg_ie->size = _indicationIEs->get_ricIndicationMessage_size();
423   ASN_SEQUENCE_ADD(&(ric_indication->protocolIEs), &(IE_array[ie_index]));
424
425
426   // optional call process id ..
427   if (_indicationIEs->get_is_callProcessID()){
428     ie_index++;
429     RICindication_IEs_t *ies_ind_callprocessid = &IE_array[ie_index];
430     ies_ind_callprocessid->criticality = Criticality_reject;
431     ies_ind_callprocessid->id = ProtocolIE_ID_id_RICcallProcessID;
432     ies_ind_callprocessid->value.present = RICindication_IEs__value_PR_RICcallProcessID;
433     RICcallProcessID_t *riccallprocessid_ie = &ies_ind_callprocessid->value.choice.RICcallProcessID;
434     riccallprocessid_ie->buf = (uint8_t*)_indicationIEs->get_ricCallProcessId();
435     riccallprocessid_ie->size = _indicationIEs->get_ricCallProcessId_size();
436     ASN_SEQUENCE_ADD(&(ric_indication->protocolIEs), &(IE_array[ie_index]));
437   }
438
439   return true;
440
441 };
442
443 #endif /* SRC_XAPP_ASN_E2AP_E2AP_INDICATION_HPP_ */