E2AP Abstraction Changes
[ric-app/hw.git] / src / xapp-asn / e2ap / e2ap_control.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 /*
21  * control.hpp
22  *
23  *  Created on: Oct 10, 2020
24  *      Author: sjana
25  */
26 /*RICcontrolRequest ::= SEQUENCE {
27         protocolIEs                                     ProtocolIE-Container    {{RICcontrolRequest-IEs}},
28         ...
29 }
30
31 RICcontrolRequest-IEs E2AP-PROTOCOL-IES ::= {
32         { ID id-RICrequestID                            CRITICALITY reject      TYPE RICrequestID                                       PRESENCE mandatory      }|
33         { ID id-RANfunctionID                           CRITICALITY reject      TYPE RANfunctionID                                      PRESENCE mandatory      }|
34         { ID id-RICcallProcessID                        CRITICALITY reject      TYPE RICcallProcessID                           PRESENCE optional       }|
35         { ID id-RICcontrolHeader                        CRITICALITY reject      TYPE RICcontrolHeader                           PRESENCE mandatory      }|
36         { ID id-RICcontrolMessage                       CRITICALITY reject      TYPE RICcontrolMessage                          PRESENCE mandatory      }|
37         { ID id-RICcontrolAckRequest            CRITICALITY reject      TYPE RICcontrolAckRequest                       PRESENCE optional       },
38         ...
39 }
40 */
41
42 #ifndef SRC_XAPP_ASN_E2AP_E2AP_CONTROL_HPP_
43 #define SRC_XAPP_ASN_E2AP_E2AP_CONTROL_HPP_
44 #include <iostream>
45 #include <errno.h>
46 #include <mdclog/mdclog.h>
47 #include <sstream>
48 #include <memory>
49 #include <E2AP-PDU.h>
50 #include <InitiatingMessage.h>
51 #include <RICcontrolRequest.h>
52 #include <ProtocolIE-Field.h>
53
54 #define NUM_CONTROL_REQUEST_IES 6
55 #define IE_SIZE ((int)128)
56
57 template <typename E2SMControlHeader, typename E2SMControlMessage>
58 class E2APControlMessage{
59
60 public:
61   class ControlRequestIEs{
62   private:
63             long int ricRequestorID , ranFunctionID, ricCallProcessID,  ricControlAckRequest;
64             unsigned char ricControlHeader[IE_SIZE];
65             size_t ricControlHeader_size=IE_SIZE;
66             unsigned char ricControlMessage[IE_SIZE];
67             size_t ricControlMessage_size=IE_SIZE;
68             unsigned char ricCallProcessId[IE_SIZE];
69             size_t ricCallProcessId_size = IE_SIZE;
70             bool is_ricCallProcessId;
71
72           public:
73             ControlRequestIEs(void):ricRequestorID(1), ranFunctionID(1), ricCallProcessID(0), ricControlAckRequest(-1),is_ricCallProcessId(false){};
74             void* get_ricControlMessage(){return this->ricControlMessage; };
75             void* get_ricControlHeader(){return this->ricControlHeader; };
76             void* get_ricCallProcessId(){return this->ricCallProcessId;};
77
78             size_t get_ricControlMessageSize(){return this->ricControlMessage_size; };
79             size_t get_ricControlHeaderSize(){return this->ricControlHeader_size; };
80             size_t get_ricCallProcessIdSize(){return this->ricCallProcessId_size;};
81
82             long int get_ricRequestorID(){return this->ricRequestorID;};
83             long int get_ranFunctionID(){return this->ranFunctionID;};
84             long int get_ricControlAckRequest(){return this->ricControlAckRequest;};
85             bool get_is_ricCallProcessId(){return is_ricCallProcessId;};
86             ControlRequestIEs& set_ricControlHeader(E2SMControlHeader headerObj){
87                 bool res = headerObj.encode(&(this->ricControlHeader)[0],&this->ricControlHeader_size);
88                 if(!res){
89                                 mdclog_write(MDCLOG_ERR, "Failed to encode: %s","RIC Control Header");
90                                 mdclog_write(MDCLOG_ERR, "Error during encode: %s",headerObj.get_error());
91                 } else {
92                                 mdclog_write(MDCLOG_INFO, "Successfully encoded: %s","RIC Control Header");
93                 }
94
95                 return *this;
96             }
97             ControlRequestIEs& set_ricControlMessage(E2SMControlMessage msgObj){
98                 bool res = msgObj.encode(&(this->ricControlMessage)[0],&this->ricControlMessage_size);
99                 if(!res){
100                              mdclog_write(MDCLOG_ERR, "Failed to encode: %s","RIC Control Message");
101                              mdclog_write(MDCLOG_ERR, "Error during encode: %s",msgObj.get_error());
102                         } else {
103                              mdclog_write(MDCLOG_INFO, "Successfully encoded: %s","RIC Control Message");
104                 }
105                         return *this;
106             }
107
108             ControlRequestIEs& set_ricCallProcessID(unsigned char* callproc, size_t callproc_size){
109                 is_ricCallProcessId = true;
110                 memcpy(ricCallProcessId, callproc, callproc_size); ricCallProcessId_size = callproc_size;
111                 return *this;
112             }
113
114             ControlRequestIEs& set_ricRequestorID(long int reqID){this->ricRequestorID = reqID; return *this;}
115             ControlRequestIEs& set_ranFunctionID(long int funcID){this->ranFunctionID = funcID; return *this;}
116
117   };
118   E2APControlMessage(ControlRequestIEs &);
119  ~E2APControlMessage(void);
120   bool encode(unsigned char *, size_t *);
121   ControlRequestIEs& getIEs(){ return *_cntrlIEs.get();};
122   std::string get_error(void) const {return _error_string ; };
123 private:
124
125   E2AP_PDU_t * _e2ap_pdu_obj;
126   InitiatingMessage_t *_initMsg;
127   RICcontrolRequest_IEs_t *IE_array;
128   std::string _error_string;
129   bool setfields(InitiatingMessage_t *);
130   std::unique_ptr<ControlRequestIEs> _cntrlIEs;
131   char _errbuf[128];
132   size_t _errbuf_len = 128;
133 };
134
135 template <typename T1, typename T2>
136 E2APControlMessage<T1,T2>::E2APControlMessage(ControlRequestIEs &controlObj){
137
138   _cntrlIEs = std::make_unique<ControlRequestIEs>();
139   *_cntrlIEs = controlObj;
140
141   _e2ap_pdu_obj = 0;
142   _e2ap_pdu_obj = (E2AP_PDU_t * )calloc(1, sizeof(E2AP_PDU_t));
143   assert(_e2ap_pdu_obj != 0);
144
145   _initMsg = 0;
146   _initMsg = (InitiatingMessage_t * )calloc(1, sizeof(InitiatingMessage_t));
147   assert(_initMsg != 0);
148
149   IE_array = 0;
150   IE_array = (RICcontrolRequest_IEs_t *)calloc(NUM_CONTROL_REQUEST_IES, sizeof(RICcontrolRequest_IEs_t));
151   assert(IE_array != 0);
152
153   _e2ap_pdu_obj->present = E2AP_PDU_PR_initiatingMessage;
154   _e2ap_pdu_obj->choice.initiatingMessage = _initMsg;
155
156
157 };
158
159
160 // Clear assigned protocolIE list from RIC control_request IE container
161 template <typename T1, typename T2>
162 E2APControlMessage<T1,T2>::~E2APControlMessage(void){
163
164   mdclog_write(MDCLOG_DEBUG, "Freeing E2AP Control Request object memory");
165
166   RICcontrolRequest_t *ricControl_Request  = &(_initMsg->value.choice.RICcontrolRequest);
167   for(int i = 0; i < ricControl_Request->protocolIEs.list.size; i++){
168     ricControl_Request->protocolIEs.list.array[i] = 0;
169   }
170
171   if (ricControl_Request->protocolIEs.list.size > 0){
172     free(ricControl_Request->protocolIEs.list.array);
173     ricControl_Request->protocolIEs.list.size = 0;
174     ricControl_Request->protocolIEs.list.count = 0;
175   }
176
177   free(IE_array);
178   free(_initMsg);
179   _e2ap_pdu_obj->choice.initiatingMessage = 0;
180
181   ASN_STRUCT_FREE(asn_DEF_E2AP_PDU, _e2ap_pdu_obj);
182   mdclog_write(MDCLOG_DEBUG, "Freed E2AP Control Request object memory");
183
184 }
185
186 template <typename T1, typename T2>
187 bool E2APControlMessage<T1,T2>::encode(unsigned char *buf, size_t *size){
188
189   _initMsg->procedureCode = ProcedureCode_id_RICcontrol;
190   _initMsg->criticality = Criticality_ignore;
191   _initMsg->value.present = InitiatingMessage__value_PR_RICcontrolRequest;
192
193   bool res;
194
195   res = setfields(_initMsg);
196   if (!res){
197     return false;
198   }
199
200   int ret_constr = asn_check_constraints(&asn_DEF_E2AP_PDU, (void *) _e2ap_pdu_obj, _errbuf, &_errbuf_len);
201   if(ret_constr){
202     _error_string.assign(_errbuf, _errbuf_len);
203     _error_string = "Constraints failed for encoding control . Reason = " + _error_string;
204     return false;
205   }
206
207   xer_fprint(stdout, &asn_DEF_E2AP_PDU, _e2ap_pdu_obj);
208
209   asn_enc_rval_t retval = asn_encode_to_buffer(0, ATS_ALIGNED_BASIC_PER, &asn_DEF_E2AP_PDU, _e2ap_pdu_obj, buf, *size);
210
211   if(retval.encoded == -1){
212     _error_string.assign(strerror(errno));
213     return false;
214   }
215   else {
216     if(*size < retval.encoded){
217       std::stringstream ss;
218       ss  <<"Error encoding event trigger definition. Reason =  encoded pdu size " << retval.encoded << " exceeds buffer size " << *size << std::endl;
219       _error_string = ss.str();
220       return false;
221     }
222   }
223
224   *size = retval.encoded;
225   return true;
226
227 }
228
229 template <typename T1, typename T2>
230 bool E2APControlMessage<T1,T2>::setfields(InitiatingMessage_t *_initMsg){
231   unsigned int ie_index;
232
233   if (_initMsg == 0){
234     _error_string = "Invalid reference for E2AP Control_Request message in set_fields";
235     return false;
236   }
237
238   RICcontrolRequest_t * E2APControlMessage = &(_initMsg->value.choice.RICcontrolRequest);
239   E2APControlMessage->protocolIEs.list.count = 0; // reset
240
241   // for(i = 0; i < NUM_CONTROL_REQUEST_IES;i++){
242   //   memset(&(IE_array[i]), 0, sizeof(RICcontrolRequest_IEs_t));
243   // }
244
245   // Mandatory IE
246   ie_index = 0;
247   RICcontrolRequest_IEs_t *ies_ricreq = &IE_array[ie_index];
248   ies_ricreq->criticality = Criticality_reject;
249   ies_ricreq->id = ProtocolIE_ID_id_RICrequestID;
250   ies_ricreq->value.present = RICcontrolRequest_IEs__value_PR_RICrequestID;
251   RICrequestID_t *ricrequest_ie = &ies_ricreq->value.choice.RICrequestID;
252   ricrequest_ie->ricRequestorID = this->getIEs().get_ricRequestorID();
253   //ricrequest_ie->ricRequestSequenceNumber = dinput.req_seq_no;
254   ASN_SEQUENCE_ADD(&(E2APControlMessage->protocolIEs), &(IE_array[ie_index]));
255
256   // Mandatory IE
257   ie_index = 1;
258   RICcontrolRequest_IEs_t *ies_ranfunc = &IE_array[ie_index];
259   ies_ranfunc->criticality = Criticality_reject;
260   ies_ranfunc->id = ProtocolIE_ID_id_RANfunctionID;
261   ies_ranfunc->value.present = RICcontrolRequest_IEs__value_PR_RANfunctionID;
262   RANfunctionID_t *ranfunction_ie = &ies_ranfunc->value.choice.RANfunctionID;
263   *ranfunction_ie = this->getIEs().get_ranFunctionID();
264   ASN_SEQUENCE_ADD(&(E2APControlMessage->protocolIEs), &(IE_array[ie_index]));
265
266
267   // Mandatory IE
268   ie_index = 2;
269   RICcontrolRequest_IEs_t *ies_richead = &IE_array[ie_index];
270   ies_richead->criticality = Criticality_reject;
271   ies_richead->id = ProtocolIE_ID_id_RICcontrolHeader;
272   ies_richead->value.present = RICcontrolRequest_IEs__value_PR_RICcontrolHeader;
273   RICcontrolHeader_t *richeader_ie = &ies_richead->value.choice.RICcontrolHeader;
274   richeader_ie->buf = (uint8_t*)this->getIEs().get_ricControlHeader();
275   richeader_ie->size = this->getIEs().get_ricControlHeaderSize();
276   ASN_SEQUENCE_ADD(&(E2APControlMessage->protocolIEs), &(IE_array[ie_index]));
277
278   // Mandatory IE
279   ie_index = 3;
280   RICcontrolRequest_IEs_t *ies_indmsg = &IE_array[ie_index];
281   ies_indmsg->criticality = Criticality_reject;
282   ies_indmsg->id = ProtocolIE_ID_id_RICcontrolMessage;
283   ies_indmsg->value.present = RICcontrolRequest_IEs__value_PR_RICcontrolMessage;
284   RICcontrolMessage_t *ricmsg_ie = &ies_indmsg->value.choice.RICcontrolMessage;
285   ricmsg_ie->buf = (uint8_t*)this->getIEs().get_ricControlMessage();
286   ricmsg_ie->size = this->getIEs().get_ricControlMessageSize();
287   ASN_SEQUENCE_ADD(&(E2APControlMessage->protocolIEs), &(IE_array[ie_index]));
288
289   // Optional IE
290   ie_index = 4;
291   if (this->getIEs().get_ricControlAckRequest()>= 0){
292     RICcontrolRequest_IEs_t *ies_indtyp = &IE_array[ie_index];
293     ies_indtyp->criticality = Criticality_reject;
294     ies_indtyp->id = ProtocolIE_ID_id_RICcontrolAckRequest;
295     ies_indtyp->value.present = RICcontrolRequest_IEs__value_PR_RICcontrolAckRequest;
296     RICcontrolAckRequest_t *ricackreq_ie = &ies_indtyp->value.choice.RICcontrolAckRequest;
297     *ricackreq_ie = this->getIEs().get_ricControlAckRequest();
298     ASN_SEQUENCE_ADD(&(E2APControlMessage->protocolIEs), &(IE_array[ie_index]));
299   }
300
301   // Optional IE
302   ie_index = 5;
303   if(this->getIEs().get_is_ricCallProcessId()){
304     RICcontrolRequest_IEs_t *ies_callprocid = &IE_array[ie_index];
305     ies_callprocid->criticality = Criticality_reject;
306     ies_callprocid->id = ProtocolIE_ID_id_RICcallProcessID;
307     ies_callprocid->value.present = RICcontrolRequest_IEs__value_PR_RICcallProcessID;
308     RICcallProcessID_t *riccallprocessid_ie = &ies_callprocid->value.choice.RICcallProcessID;
309     riccallprocessid_ie->buf = (uint8_t*)this->getIEs().get_ricCallProcessId();
310     riccallprocessid_ie->size = this->getIEs().get_ricCallProcessIdSize();
311     ASN_SEQUENCE_ADD(&(E2APControlMessage->protocolIEs), &(IE_array[ie_index]));
312
313   }
314   return true;
315
316 };
317
318 #endif /* SRC_XAPP_ASN_E2AP_E2AP_CONTROL_HPP_ */