1 /*******************************************************************************
2 ################################################################################
3 # Copyright (c) [2017-2019] [Radisys] #
5 # Licensed under the Apache License, Version 2.0 (the "License"); #
6 # you may not use this file except in compliance with the License. #
7 # You may obtain a copy of the License at #
9 # http://www.apache.org/licenses/LICENSE-2.0 #
11 # Unless required by applicable law or agreed to in writing, software #
12 # distributed under the License is distributed on an "AS IS" BASIS, #
13 # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. #
14 # See the License for the specific language governing permissions and #
15 # limitations under the License. #
16 ################################################################################
17 *******************************************************************************/
19 /* This file contains E2AP message handler functions */
20 #include "common_def.h"
21 #include "OCTET_STRING.h"
22 #include "BIT_STRING.h"
23 #include "odu_common_codec.h"
25 #include "ric_stub_sctp.h"
26 #include "ric_e2ap_msg_hdl.h"
27 #include "GlobalE2node-gNB-ID.h"
28 #include "ProtocolIE-FieldE2.h"
29 #include "InitiatingMessageE2.h"
30 #include "SuccessfulOutcomeE2.h"
36 /*******************************************************************
38 * @brief Sends E2 msg over SCTP
42 * Function : SendE2APMsg
44 * Functionality: Sends E2 msg over SCTP
46 * @params[in] Region region
48 * @return ROK - success
51 * ****************************************************************/
53 S16 SendE2APMsg(Region region, Pool pool)
57 if(ODU_GET_MSG_BUF(region, pool, &mBuf) == ROK)
59 if(ODU_ADD_POST_MSG_MULT((Data *)encBuf, encBufSize, mBuf) == ROK)
61 ODU_PRINT_MSG(mBuf, 0,0);
63 if(sctpSend(mBuf) != ROK)
65 DU_LOG("\nERROR --> E2AP : SCTP Send for E2 failed");
66 ODU_PUT_MSG_BUF(mBuf);
72 DU_LOG("\nERROR --> E2AP : ODU_ADD_POST_MSG_MULT failed");
73 ODU_PUT_MSG_BUF(mBuf);
76 ODU_PUT_MSG_BUF(mBuf);
80 DU_LOG("\nERROR --> E2AP : Failed to allocate memory");
87 /*******************************************************************
89 * @brief Builds Global RIC Id Params
93 * Function : BuildGlobalRicId
95 * Functionality: Building the Plmn and ric id
97 * @params[in] GlobalRIC_ID_t *ricId
98 * @return ROK - success
101 * ****************************************************************/
103 S16 BuildGlobalRicId(GlobalRIC_ID_t *ricId)
106 uint8_t byteSize = 3;
110 ricId->pLMN_Identity.size = byteSize * sizeof(uint8_t);
111 RIC_ALLOC(ricId->pLMN_Identity.buf, ricId->pLMN_Identity.size);
112 buildPlmnId(ricCfgParams.plmn , ricId->pLMN_Identity.buf);
114 ricId->ric_ID.size = byteSize * sizeof(uint8_t);
115 RIC_ALLOC(ricId->ric_ID.buf, ricId->ric_ID.size);
116 fillBitString(&ricId->ric_ID, unused, byteSize, val);
121 /*******************************************************************
123 * @brief Builds and sends the E2SetupResponse
127 * Function : BuildAndSendE2SetupRsp
129 * Functionality: Constructs the F1SetupResponse message and sends
130 * it back to the DU through SCTP.
132 * @params[in] void **buf,Buffer to which encoded pattern is written into
133 * @params[in] int *size,size of buffer
135 * @return ROK - success
138 * ****************************************************************/
139 S16 BuildAndSendE2SetupRsp()
141 E2AP_PDU_t *e2apMsg = NULL;
142 E2setupResponse_t *e2SetupRsp;
143 asn_enc_rval_t encRetVal;
148 DU_LOG("\nINFO --> E2AP : Building E2 Setup Response\n");
150 RIC_ALLOC(e2apMsg, sizeof(E2AP_PDU_t));
153 DU_LOG("\nERROR --> E2AP : Memory allocation for E2AP-PDU failed");
156 e2apMsg->present = E2AP_PDU_PR_successfulOutcome;
157 RIC_ALLOC(e2apMsg->choice.successfulOutcome, sizeof(SuccessfulOutcomeE2_t));
158 if(e2apMsg->choice.successfulOutcome == NULLP)
160 DU_LOG("\nERROR --> E2AP : Memory allocation for E2AP-PDU failed");
161 RIC_FREE(e2apMsg, sizeof(E2AP_PDU_t));
165 e2apMsg->choice.successfulOutcome->procedureCode = ProcedureCodeE2_id_E2setup;
166 e2apMsg->choice.successfulOutcome->criticality = CriticalityE2_reject;
167 e2apMsg->choice.successfulOutcome->value.present = \
168 SuccessfulOutcomeE2__value_PR_E2setupResponse;
169 e2SetupRsp = &e2apMsg->choice.successfulOutcome->value.choice.E2setupResponse;
172 e2SetupRsp->protocolIEs.list.count = elementCnt;
173 e2SetupRsp->protocolIEs.list.size = elementCnt * sizeof(E2setupResponseIEs_t);
175 RIC_ALLOC(e2SetupRsp->protocolIEs.list.array, \
176 e2SetupRsp->protocolIEs.list.size);
177 if(e2SetupRsp->protocolIEs.list.array == NULLP)
179 DU_LOG("\nERROR --> E2AP : Memory allocation for E2ResponseIEs failed");
180 RIC_FREE(e2apMsg->choice.successfulOutcome, sizeof(SuccessfulOutcomeE2_t));
181 RIC_FREE(e2apMsg, sizeof(E2AP_PDU_t));
185 for(idx=0; idx<elementCnt; idx++)
187 RIC_ALLOC(e2SetupRsp->protocolIEs.list.array[idx], \
188 sizeof(E2setupResponseIEs_t));
189 if(e2SetupRsp->protocolIEs.list.array[idx] == NULLP)
191 RIC_FREE(e2SetupRsp->protocolIEs.list.array,\
192 e2SetupRsp->protocolIEs.list.size);
193 RIC_FREE(e2apMsg->choice.successfulOutcome, \
194 sizeof(SuccessfulOutcomeE2_t));
195 RIC_FREE(e2apMsg, sizeof(E2AP_PDU_t));
201 e2SetupRsp->protocolIEs.list.array[idx]->id = ProtocolIE_IDE2_id_GlobalRIC_ID;
202 e2SetupRsp->protocolIEs.list.array[idx]->criticality = CriticalityE2_reject;
203 e2SetupRsp->protocolIEs.list.array[idx]->value.present = \
204 E2setupResponseIEs__value_PR_GlobalRIC_ID;
206 BuildGlobalRicId(&(e2SetupRsp->protocolIEs.list.array[idx]->value.choice.GlobalRIC_ID));
208 xer_fprint(stdout, &asn_DEF_E2AP_PDU, e2apMsg);
209 memset(encBuf, 0, ENC_BUF_MAX_LEN);
211 encRetVal = aper_encode(&asn_DEF_E2AP_PDU, 0, e2apMsg, PrepFinalEncBuf, encBuf);
213 /* Check encode results */
214 if(encRetVal.encoded == ENCODE_FAIL)
216 DU_LOG("\nERROR --> E2AP : Could not encode E2SetupResponse structure (at %s)\n",\
217 encRetVal.failed_type ? encRetVal.failed_type->name : "unknown");
222 DU_LOG("\nDEBUG --> E2AP : Created APER encoded buffer for E2SetupResponse\n");
223 for(int i=0; i< encBufSize; i++)
225 DU_LOG("%x",encBuf[i]);
230 if(SendE2APMsg(RIC_APP_MEM_REG, RIC_POOL) != ROK)
232 DU_LOG("\nERROR --> E2AP : Sending E2 Setup Response failed");
239 /*******************************************************************
241 * @brief Builds Ric Request Id
245 * Function : BuildRicRequestId
247 * Functionality: Building the Ric Request Id
249 * @params[in] RICrequestID_t *ricReqId
250 * @return ROK - success
253 * ****************************************************************/
255 S16 BuildRicRequestId(RICrequestID_t *ricReqId)
258 if(ricReqId != NULLP)
260 ricReqId->ricRequestorID = 1;
261 ricReqId->ricInstanceID = 1;
266 /*******************************************************************
268 * @brief Fills Ric Action To be Setup Item
272 * Function : fillSetupItems
274 * Functionality: Filling ricAction Id, RicActionType
276 * @params[in] RICaction_ToBeSetup_Item_t *setupItems
277 * @return pointer of type RICaction_ToBeSetup_Item_t
279 * ****************************************************************/
281 RICaction_ToBeSetup_Item_t* fillSetupItems(RICaction_ToBeSetup_Item_t *setupItems)
283 if(setupItems != NULLP)
285 setupItems->ricActionID = 0;
286 setupItems->ricActionType = RICactionType_report;
292 /*******************************************************************
294 * @brief Fills RIC Subscription Details Item List
298 * Function : fillSubsDetails
300 * Functionality: Fill the RIC Subscription Details Items List
302 * @params[in] RICaction_ToBeSetup_ItemIEs_t *items
303 * @return ROK - success
306 * ****************************************************************/
308 S16 fillSubsDetails(RICaction_ToBeSetup_ItemIEs_t *items)
312 items->id = ProtocolIE_IDE2_id_RICaction_ToBeSetup_Item;
313 items->criticality = CriticalityE2_ignore;
314 items->value.present = RICaction_ToBeSetup_ItemIEs__value_PR_RICaction_ToBeSetup_Item;
315 fillSetupItems(&(items->value.choice.RICaction_ToBeSetup_Item));
320 /*******************************************************************
322 * @brief builds RIC Subscription Details
326 * Function : BuildsRicSubsDetails
328 * Functionality: Builds the RIC Subscription Details
330 * @params[in] RICsubscriptionDetails_t *subsDetails
331 * @return ROK - success
334 * ****************************************************************/
336 S16 BuildRicSubsDetails(RICsubscriptionDetails_t *subsDetails)
341 if(subsDetails != NULLP)
343 /* Octet string to be build here */
344 /* Sending PLMN as Octect string */
345 uint8_t byteSize = 3;
346 subsDetails->ricEventTriggerDefinition.size = byteSize * sizeof(uint8_t);
347 RIC_ALLOC(subsDetails->ricEventTriggerDefinition.buf, subsDetails->ricEventTriggerDefinition.size);
348 buildPlmnId(ricCfgParams.plmn, subsDetails->ricEventTriggerDefinition.buf);
350 subsDetails->ricAction_ToBeSetup_List.list.count = elementCnt;
351 subsDetails->ricAction_ToBeSetup_List.list.size = \
352 elementCnt * sizeof(RICaction_ToBeSetup_ItemIEs_t);
353 RIC_ALLOC(subsDetails->ricAction_ToBeSetup_List.list.array, \
354 subsDetails->ricAction_ToBeSetup_List.list.size);
355 if(subsDetails->ricAction_ToBeSetup_List.list.array == NULLP)
357 DU_LOG("\nERROR --> E2AP : Memory allocation for RICactionToBeSetup Items failed");
360 RIC_ALLOC(subsDetails->ricAction_ToBeSetup_List.list.array[0],\
361 sizeof(RICaction_ToBeSetup_ItemIEs_t));
362 fillSubsDetails(subsDetails->ricAction_ToBeSetup_List.list.array[0]);
367 /*******************************************************************
369 * @brief Builds and Send the RicSubscriptionReq
373 * Function : BuildAndSendRicSubscriptionReq
375 * Functionality:Fills the RicSubscriptionReq
377 * @return ROK - success
380 ******************************************************************/
382 S16 BuildAndSendRicSubscriptionReq()
385 E2AP_PDU_t *e2apRicMsg = NULL;
386 RICsubscriptionRequest_t *ricSubscriptionReq;
391 asn_enc_rval_t encRetVal; /* Encoder return value */
392 ricSubsStatus = TRUE;
394 DU_LOG("\nINFO --> E2AP : Building RIC Subscription Request\n");
396 RIC_ALLOC(e2apRicMsg, sizeof(E2AP_PDU_t));
397 if(e2apRicMsg == NULLP)
399 DU_LOG("\nERROR --> E2AP : Memory allocation for E2AP-PDU failed");
403 e2apRicMsg->present = E2AP_PDU_PR_initiatingMessage;
404 RIC_ALLOC(e2apRicMsg->choice.initiatingMessage, sizeof(InitiatingMessageE2_t));
405 if(e2apRicMsg->choice.initiatingMessage == NULLP)
407 DU_LOG("\nERROR --> E2AP : Memory allocation for E2AP-PDU failed");
408 RIC_FREE(e2apRicMsg, sizeof(E2AP_PDU_t));
411 e2apRicMsg->choice.initiatingMessage->procedureCode = ProcedureCodeE2_id_RICsubscription;
412 e2apRicMsg->choice.initiatingMessage->criticality = CriticalityE2_reject;
413 e2apRicMsg->choice.initiatingMessage->value.present = InitiatingMessageE2__value_PR_RICsubscriptionRequest;
415 RIC_ALLOC(ricSubscriptionReq, sizeof(RICsubscriptionRequest_t));
416 ricSubscriptionReq = &e2apRicMsg->choice.initiatingMessage->value.choice.RICsubscriptionRequest;
419 ricSubscriptionReq->protocolIEs.list.count = elementCnt;
420 ricSubscriptionReq->protocolIEs.list.size = elementCnt * sizeof(RICsubscriptionRequest_IEs_t);
422 /* Initialize the subscription members */
423 RIC_ALLOC(ricSubscriptionReq->protocolIEs.list.array, \
424 ricSubscriptionReq->protocolIEs.list.size);
425 if(ricSubscriptionReq->protocolIEs.list.array == NULLP)
427 DU_LOG("\nERROR --> E2AP : Memory allocation for RICSubscriptionRequestIEs failed");
428 RIC_FREE(e2apRicMsg->choice.initiatingMessage, sizeof(InitiatingMessageE2_t));
429 RIC_FREE(e2apRicMsg, (Size)sizeof(E2AP_PDU_t));
433 for(idx=0; idx<elementCnt; idx++)
435 RIC_ALLOC(ricSubscriptionReq->protocolIEs.list.array[idx],\
436 sizeof(RICsubscriptionRequest_IEs_t));
437 if(ricSubscriptionReq->protocolIEs.list.array[idx] == NULLP)
439 for(ieId=0; ieId<idx; ieId++)
441 RIC_FREE(ricSubscriptionReq->protocolIEs.list.array[ieId],\
442 sizeof(RICsubscriptionRequest_IEs_t));
444 RIC_FREE(ricSubscriptionReq->protocolIEs.list.array,\
445 ricSubscriptionReq->protocolIEs.list.size);
446 RIC_FREE(e2apRicMsg->choice.initiatingMessage, \
447 sizeof(InitiatingMessageE2_t));
448 RIC_FREE(e2apRicMsg, sizeof(E2AP_PDU_t));
453 /* Filling RIC Request Id */
455 ricSubscriptionReq->protocolIEs.list.array[idx]->id = ProtocolIE_IDE2_id_RICrequestID;
456 ricSubscriptionReq->protocolIEs.list.array[idx]->criticality = CriticalityE2_reject;
457 ricSubscriptionReq->protocolIEs.list.array[idx]->value.present =\
458 RICsubscriptionRequest_IEs__value_PR_RICrequestID;
460 BuildRicRequestId(&ricSubscriptionReq->protocolIEs.list.array[idx]->value.choice.RICrequestID);
463 /* Filling RAN Function Id */
465 ricSubscriptionReq->protocolIEs.list.array[idx]->id = ProtocolIE_IDE2_id_RANfunctionID;
466 ricSubscriptionReq->protocolIEs.list.array[idx]->criticality = CriticalityE2_reject;
467 ricSubscriptionReq->protocolIEs.list.array[idx]->value.present =\
468 RICsubscriptionRequest_IEs__value_PR_RANfunctionID;
469 ricSubscriptionReq->protocolIEs.list.array[idx]->value.choice.RANfunctionID = 1;
472 /* Filling RIC Subscription Details */
474 ricSubscriptionReq->protocolIEs.list.array[idx]->id = ProtocolIE_IDE2_id_RICsubscriptionDetails;
475 ricSubscriptionReq->protocolIEs.list.array[idx]->criticality = CriticalityE2_reject;
476 ricSubscriptionReq->protocolIEs.list.array[idx]->value.present =\
477 RICsubscriptionRequest_IEs__value_PR_RICsubscriptionDetails;
479 BuildRicSubsDetails(&(ricSubscriptionReq->protocolIEs.list.array[idx]->value.choice.RICsubscriptionDetails));
482 /* Prints the Msg formed */
483 xer_fprint(stdout, &asn_DEF_E2AP_PDU, e2apRicMsg);
485 memset(encBuf, 0, ENC_BUF_MAX_LEN);
487 encRetVal = aper_encode(&asn_DEF_E2AP_PDU, 0, e2apRicMsg, PrepFinalEncBuf,\
489 if(encRetVal.encoded == ENCODE_FAIL)
491 DU_LOG("\nERROR --> E2AP : Could not encode RicSubscriptionRequest structure (at %s)\n",\
492 encRetVal.failed_type ? encRetVal.failed_type->name : "unknown");
497 DU_LOG("\nDEBUG --> E2AP : Created APER encoded buffer for RicSubscriptionRequest\n");
498 for(int i=0; i< encBufSize; i++)
500 DU_LOG("%x",encBuf[i]);
506 if(SendE2APMsg(RIC_APP_MEM_REG, RIC_POOL) != ROK)
508 DU_LOG("\nERROR --> E2AP : Sending RIC subscription Request failed");
516 /*******************************************************************
518 * @brief Handles received E2AP message and sends back response
522 * Function : E2APMsgHdlr
525 * - Decodes received E2AP control message
526 * - Prepares response message, encodes and sends to SCTP
529 * @return ROK - success
532 * ****************************************************************/
533 void E2APMsgHdlr(Buffer *mBuf)
540 asn_dec_rval_t rval; /* Decoder return value */
541 E2AP_PDU_t e2apasnmsg ;
543 DU_LOG("\nINFO --> E2AP : Received E2AP message buffer");
544 ODU_PRINT_MSG(mBuf, 0,0);
546 /* Copy mBuf into char array to decode it */
547 ODU_GET_MSG_LEN(mBuf, &recvBufLen);
548 RIC_ALLOC(recvBuf, (Size)recvBufLen);
552 DU_LOG("\nERROR --> E2AP : Memory allocation failed");
555 if(ODU_COPY_MSG_TO_FIX_BUF(mBuf, 0, recvBufLen, (Data *)recvBuf, ©Cnt) != ROK)
557 DU_LOG("\nERROR --> E2AP : Failed while copying %d", copyCnt);
561 DU_LOG("\nDEBUG --> E2AP : Received flat buffer to be decoded : ");
562 for(i=0; i< recvBufLen; i++)
564 DU_LOG("%x",recvBuf[i]);
567 /* Decoding flat buffer into E2AP messsage */
568 e2apMsg = &e2apasnmsg;
569 memset(e2apMsg, 0, sizeof(E2AP_PDU_t));
571 rval = aper_decode(0, &asn_DEF_E2AP_PDU, (void **)&e2apMsg, recvBuf, recvBufLen, 0, 0);
572 RIC_FREE(recvBuf, (Size)recvBufLen);
574 if(rval.code == RC_FAIL || rval.code == RC_WMORE)
576 DU_LOG("\nERROR --> E2AP : ASN decode failed");
580 xer_fprint(stdout, &asn_DEF_E2AP_PDU, e2apMsg);
582 switch(e2apMsg->present)
584 case E2AP_PDU_PR_initiatingMessage:
586 switch(e2apMsg->choice.initiatingMessage->value.present)
588 case InitiatingMessageE2__value_PR_E2setupRequest:
590 DU_LOG("\nINFO --> E2AP : E2 setup request received");
591 BuildAndSendE2SetupRsp();
594 case InitiatingMessageE2__value_PR_RICindication:
596 DU_LOG("\nINFO --> E2AP : RIC Indication Acknowledged");
601 DU_LOG("\nERROR --> E2AP : Invalid type of intiating message [%d]",e2apMsg->choice.initiatingMessage->value.present);
604 }/* End of switch(initiatingMessage) */
607 case E2AP_PDU_PR_successfulOutcome:
609 switch(e2apMsg->choice.successfulOutcome->value.present)
611 case SuccessfulOutcomeE2__value_PR_RICsubscriptionResponse:
613 DU_LOG("\nINFO --> E2AP : RICsubscriptionResponse Msg Acknowledged");
618 DU_LOG("\nERROR --> E2AP : Invalid type of successfulOutcome message [%d]",e2apMsg->choice.successfulOutcome->value.present);
627 DU_LOG("\nERROR --> E2AP : Invalid type message type ");
631 }/* End of switch(e2apMsg->present) */
634 BuildAndSendRicSubscriptionReq();
636 } /* End of E2APMsgHdlr */
639 /**********************************************************************
641 **********************************************************************/