Added IndicationMessage
[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  * 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 #define IE_SIZE ((int)128)
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;
89
90                 public:
91                         IndicationIEs(void) : ricRequestorID(0), ranFunctionID(0), ricActionID(0),ricIndicationSN(0), ricIndicationType(0),is_callProcessID(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
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; 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   unsigned int ricIndicationIEs_Count;
170
171   std::string _error_string;
172   char _errbuf[128];
173   size_t _errbuf_len = 128;
174
175   bool setfields( InitiatingMessage_t *);
176 };
177
178 template<typename T1, typename T2>
179 E2APIndication<T1,T2>::E2APIndication(IndicationIEs& ieObj){
180
181   ricIndicationIEs_Count = 8;
182
183   e2ap_pdu_obj = 0;
184   e2ap_pdu_obj = (E2AP_PDU_t * )calloc(1, sizeof(E2AP_PDU_t));
185   assert(e2ap_pdu_obj != 0);
186
187   initMsg = 0;
188   initMsg = (InitiatingMessage_t * )calloc(1, sizeof(InitiatingMessage_t));
189   assert(initMsg != 0);
190
191   IE_array = 0;
192   IE_array = (RICindication_IEs_t *)calloc(ricIndicationIEs_Count, sizeof(RICindication_IEs_t));
193   assert(IE_array != 0);
194
195   e2ap_pdu_obj->present = E2AP_PDU_PR_initiatingMessage;
196   e2ap_pdu_obj->choice.initiatingMessage = initMsg;
197
198   _indicationIEs = std::make_unique<IndicationIEs>();
199   *_indicationIEs = ieObj;
200
201 };
202 template<typename T1, typename T2>
203 E2APIndication<T1,T2>::E2APIndication(unsigned char *buf, size_t *size){
204           e2ap_pdu_obj = 0;
205           initMsg = 0;
206           IE_array = 0;
207
208           _indicationIEs = std::make_unique<IndicationIEs>();
209            bool status =  this->decode(buf, size);
210            if(!status)
211                    throw "E2AP Indication Decode Failed: "+this->get_error();
212 }
213
214
215 // Clear assigned protocolIE list from RIC indication IE container
216 template<typename T1, typename T2>
217 E2APIndication<T1,T2>::~E2APIndication(void){
218
219   mdclog_write(MDCLOG_DEBUG, "Freeing E2AP Indication object memory");
220   RICindication_t *ricIndication  = &(initMsg->value.choice.RICindication);
221   for(int i = 0; i < ricIndication->protocolIEs.list.size; i++){
222     ricIndication->protocolIEs.list.array[i] = 0;
223   }
224   if (ricIndication->protocolIEs.list.size > 0){
225     free(ricIndication->protocolIEs.list.array);
226     ricIndication->protocolIEs.list.array = 0;
227     ricIndication->protocolIEs.list.count = 0;
228     ricIndication->protocolIEs.list.size = 0;
229   }
230
231   free(IE_array);
232   ASN_STRUCT_FREE(asn_DEF_E2AP_PDU, e2ap_pdu_obj);
233   mdclog_write(MDCLOG_DEBUG, "Freed E2AP Indication object memory");
234 }
235
236 template<typename T1, typename T2>
237 bool E2APIndication<T1, T2>::decode(unsigned char *buf, size_t *size)
238 {
239
240         asn_dec_rval_t dec_res  = asn_decode(0,ATS_ALIGNED_BASIC_PER, &asn_DEF_E2AP_PDU, (void**)&(e2ap_pdu_obj), buf, *size);
241         if(dec_res.code != RC_OK){
242                          mdclog_write(MDCLOG_ERR, "Failed to decode: %s","RIC Indication Message");
243                          return false;
244         } else {
245                          mdclog_write(MDCLOG_INFO, "Successfully decoded: %s","RIC Indication Message");
246         }
247
248   xer_fprint(stdout, &asn_DEF_E2AP_PDU, e2ap_pdu_obj);
249
250   initMsg = e2ap_pdu_obj->choice.initiatingMessage;
251   //write the decoding code.
252   if (initMsg == 0){
253     _error_string = "Invalid reference for E2AP Indication message in get_fields";
254     return false;
255   }
256
257
258   for(int edx = 0; edx < initMsg->value.choice.RICindication.protocolIEs.list.count; edx++) {
259         RICindication_IEs_t *memb_ptr = initMsg->value.choice.RICindication.protocolIEs.list.array[edx];
260     switch(memb_ptr->id)
261      {
262       case (ProtocolIE_ID_id_RICindicationHeader):
263                 _indicationIEs->set_ricIndicationHeader(memb_ptr->value.choice.RICindicationHeader.buf, memb_ptr->value.choice.RICindicationHeader.size);
264       break;
265
266       case (ProtocolIE_ID_id_RICindicationMessage):
267                 _indicationIEs->set_ricIndicationMessage(memb_ptr->value.choice.RICindicationMessage.buf, memb_ptr->value.choice.RICindicationMessage.size);
268       break;
269
270       case (ProtocolIE_ID_id_RICrequestID):
271                 _indicationIEs->set_ricRequestorID(memb_ptr->value.choice.RICrequestID.ricRequestorID);
272       break;
273
274       case (ProtocolIE_ID_id_RANfunctionID):
275                 _indicationIEs->set_ranFunctionID(memb_ptr->value.choice.RANfunctionID);
276           break;
277
278       case (ProtocolIE_ID_id_RICindicationSN):
279                 _indicationIEs->set_ricIndicationSN(memb_ptr->value.choice.RICindicationSN);
280           break;
281
282       case (ProtocolIE_ID_id_RICindicationType):
283                 _indicationIEs->set_ricIndicationType(memb_ptr->value.choice.RICindicationType);
284           break;
285
286       case (ProtocolIE_ID_id_RICactionID):
287                 _indicationIEs->set_ricActionID(memb_ptr->value.choice.RICactionID);
288           break;
289
290       case (ProtocolIE_ID_id_RICcallProcessID):
291                 _indicationIEs->set_ricCallProcessID(memb_ptr->value.choice.RICcallProcessID.buf,memb_ptr->value.choice.RICcallProcessID.size);
292           break;
293
294       default:
295       break;
296       }
297
298   }
299
300   return true;
301
302 }
303
304 template<typename T1, typename T2>
305 bool E2APIndication<T1,T2>::encode(unsigned char *buf, size_t *size){
306
307   initMsg->procedureCode = ProcedureCode_id_RICindication;
308   initMsg->criticality = Criticality_ignore;
309   initMsg->value.present = InitiatingMessage__value_PR_RICindication;
310
311   bool res;
312   asn_enc_rval_t retval;
313
314   res = setfields(initMsg);
315   if (!res){
316     return false;
317   }
318
319   int ret_constr = asn_check_constraints(&asn_DEF_E2AP_PDU, e2ap_pdu_obj, _errbuf, &_errbuf_len);
320   if(ret_constr){
321     _error_string.assign(&_errbuf[0], _errbuf_len);
322     _error_string = "Error encoding E2AP Indication message. Reason = " + _error_string;
323     return false;
324   }
325
326   xer_fprint(stdout, &asn_DEF_E2AP_PDU, e2ap_pdu_obj);
327
328   retval = asn_encode_to_buffer(0, ATS_ALIGNED_BASIC_PER, &asn_DEF_E2AP_PDU, e2ap_pdu_obj, buf, *size);
329   if(retval.encoded == -1){
330     _error_string.assign(strerror(errno));
331     return false;
332   }
333
334   else {
335     if(*size < retval.encoded){
336       std::stringstream ss;
337       ss  <<"Error encoding E2AP Indication . Reason =  encoded pdu size " << retval.encoded << " exceeds buffer size " << *size << std::endl;
338       _error_string = ss.str();
339       return false;
340     }
341   }
342
343   *size = retval.encoded;
344   return true;
345
346 }
347 template<typename T1, typename T2>
348 bool E2APIndication<T1,T2>::setfields(InitiatingMessage_t *initMsg){
349   unsigned int ie_index;
350
351   if (initMsg == 0){
352     _error_string = "Invalid reference for E2AP Indication message in set_fields";
353     return false;
354   }
355
356
357   RICindication_t * ric_indication = &(initMsg->value.choice.RICindication);
358   ric_indication->protocolIEs.list.count = 0;
359
360   ie_index = 0;
361
362   RICindication_IEs_t *ies_ricreq = &IE_array[ie_index];
363   ies_ricreq->criticality = Criticality_reject;
364   ies_ricreq->id = ProtocolIE_ID_id_RICrequestID;
365   ies_ricreq->value.present = RICindication_IEs__value_PR_RICrequestID;
366   RICrequestID_t *ricrequest_ie = &ies_ricreq->value.choice.RICrequestID;
367   ricrequest_ie->ricRequestorID = _indicationIEs->get_ricRequestorID();
368   ASN_SEQUENCE_ADD(&(ric_indication->protocolIEs), &(IE_array[ie_index]));
369
370   ie_index = 1;
371   RICindication_IEs_t *ies_ranfunc = &IE_array[ie_index];
372   ies_ranfunc->criticality = Criticality_reject;
373   ies_ranfunc->id = ProtocolIE_ID_id_RANfunctionID;
374   ies_ranfunc->value.present = RICindication_IEs__value_PR_RANfunctionID;
375   RANfunctionID_t *ranfunction_ie = &ies_ranfunc->value.choice.RANfunctionID;
376   *ranfunction_ie = _indicationIEs->get_ranFunctionID();
377   ASN_SEQUENCE_ADD(&(ric_indication->protocolIEs), &(IE_array[ie_index]));
378
379   ie_index = 2;
380   RICindication_IEs_t *ies_actid = &IE_array[ie_index];
381   ies_actid->criticality = Criticality_reject;
382   ies_actid->id = ProtocolIE_ID_id_RICactionID;
383   ies_actid->value.present = RICindication_IEs__value_PR_RICactionID;
384   RICactionID_t *ricaction_ie = &ies_actid->value.choice.RICactionID;
385   *ricaction_ie = _indicationIEs->get_ricActionID();
386   ASN_SEQUENCE_ADD(&(ric_indication->protocolIEs), &(IE_array[ie_index]));
387
388   ie_index = 3;
389   RICindication_IEs_t *ies_ricsn = &IE_array[ie_index];
390   ies_ricsn->criticality = Criticality_reject;
391   ies_ricsn->id = ProtocolIE_ID_id_RICindicationSN;
392   ies_ricsn->value.present = RICindication_IEs__value_PR_RICindicationSN;
393   RICindicationSN_t *ricsn_ie = &ies_ricsn->value.choice.RICindicationSN;
394   *ricsn_ie = _indicationIEs->get_ricIndicationSN();
395   ASN_SEQUENCE_ADD(&(ric_indication->protocolIEs), &(IE_array[ie_index]));
396
397
398   ie_index = 4;
399   RICindication_IEs_t *ies_indtyp = &IE_array[ie_index];
400   ies_indtyp->criticality = Criticality_reject;
401   ies_indtyp->id = ProtocolIE_ID_id_RICindicationType;
402   ies_indtyp->value.present = RICindication_IEs__value_PR_RICindicationType;
403   RICindicationType_t *rictype_ie = &ies_indtyp->value.choice.RICindicationType;
404   *rictype_ie = _indicationIEs->get_ricIndicationType();
405   ASN_SEQUENCE_ADD(&(ric_indication->protocolIEs), &(IE_array[ie_index]));
406
407   ie_index = 5;
408   RICindication_IEs_t *ies_richead = &IE_array[ie_index];
409   ies_richead->criticality = Criticality_reject;
410   ies_richead->id = ProtocolIE_ID_id_RICindicationHeader;
411   ies_richead->value.present = RICindication_IEs__value_PR_RICindicationHeader;
412   RICindicationHeader_t *richeader_ie = &ies_richead->value.choice.RICindicationHeader;
413   richeader_ie->buf = (uint8_t*)_indicationIEs->get_ricIndicationHeader();
414   richeader_ie->size = _indicationIEs->get_ricIndicationHeader_size();
415   ASN_SEQUENCE_ADD(&(ric_indication->protocolIEs), &(IE_array[ie_index]));
416
417   ie_index = 6;
418   RICindication_IEs_t *ies_indmsg = &IE_array[ie_index];
419   ies_indmsg->criticality = Criticality_reject;
420   ies_indmsg->id = ProtocolIE_ID_id_RICindicationMessage;
421   ies_indmsg->value.present = RICindication_IEs__value_PR_RICindicationMessage;
422   RICindicationMessage_t *ricmsg_ie = &ies_indmsg->value.choice.RICindicationMessage;
423   ricmsg_ie->buf = (uint8_t*)_indicationIEs->get_ricIndicationMessage();
424   ricmsg_ie->size = _indicationIEs->get_ricIndicationMessage_size();
425   ASN_SEQUENCE_ADD(&(ric_indication->protocolIEs), &(IE_array[ie_index]));
426
427
428   // optional call process id ..
429   if (_indicationIEs->get_is_callProcessID()){
430     ie_index = 7;
431     RICindication_IEs_t *ies_ind_callprocessid = &IE_array[ie_index];
432     ies_ind_callprocessid->criticality = Criticality_reject;
433     ies_ind_callprocessid->id = ProtocolIE_ID_id_RICcallProcessID;
434     ies_ind_callprocessid->value.present = RICindication_IEs__value_PR_RICcallProcessID;
435     RICcallProcessID_t *riccallprocessid_ie = &ies_ind_callprocessid->value.choice.RICcallProcessID;
436     riccallprocessid_ie->buf = (uint8_t*)_indicationIEs->get_ricCallProcessId();
437     riccallprocessid_ie->size = _indicationIEs->get_ricCallProcessId_size();
438     ASN_SEQUENCE_ADD(&(ric_indication->protocolIEs), &(IE_array[ie_index]));
439   }
440
441   return true;
442
443 };
444
445 #endif /* SRC_XAPP_ASN_E2AP_E2AP_INDICATION_HPP_ */