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