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 */
21 #include "ric_stub_sctp.h"
22 #include "ric_e2ap_msg_hdl.h"
23 #include "GlobalE2node-gNB-ID.h"
25 char encBuf[ENC_BUF_MAX_LEN];
27 S16 SendE2APMsg(Region , Pool );
29 /*******************************************************************
31 * @brief Writes the encoded chunks into a buffer
35 * Function : PrepFinalEncBuf
37 * Functionality:Fills the encoded buffer
39 * @params[in] void *buffer,initial encoded data
40 * @params[in] size_t size,size of buffer
41 * @params[in] void *encodedBuf,final buffer
42 * @return ROK - success
45 * ****************************************************************/
46 static int PrepFinalEncBuf(const void *buffer, size_t size, void *encodedBuf)
48 memcpy(encodedBuf + encBufSize, buffer, size);
51 } /* PrepFinalEncBuf */
53 /*******************************************************************
55 * @brief Sends E2 msg over SCTP
59 * Function : SendE2APMsg
61 * Functionality: Sends E2 msg over SCTP
63 * @params[in] Region region
65 * @return ROK - success
68 * ****************************************************************/
70 S16 SendE2APMsg(Region region, Pool pool)
74 if(SGetMsg(region, pool, &mBuf) == ROK)
76 if(SAddPstMsgMult((Data *)encBuf, encBufSize, mBuf) == ROK)
80 if(sctpSend(mBuf) != ROK)
82 DU_LOG("\nF1AP : SCTP Send for E2 failed");
89 DU_LOG("\nF1AP : SAddPstMsgMult failed");
97 DU_LOG("\nF1AP : Failed to allocate memory");
104 /*******************************************************************
106 * @brief Builds PLMN ID
110 * Function : plmnBuildRic
112 * Functionality: Building the PLMN ID
114 * @params[in] PLMNID plmn
115 * OCTET_STRING_t *octe
116 * @return ROK - success
119 * ****************************************************************/
121 void plmnBuildRic(Plmn plmn, OCTET_STRING_t *octe)
125 RIC_ALLOC(octe->buf, octe->size * sizeof(U8));
126 if(octe->buf == NULLP)
131 octe->buf[0] = ((plmn.mcc[1] << 4) | (plmn.mcc[0]));
134 octe->buf[1] = ((0xf0) | (plmn.mcc[2]));
135 octe->buf[2] = ((plmn.mnc[1] << 4) | (plmn.mnc[0]));
139 octe->buf[1] = ((plmn.mnc[0] << 4) | (plmn.mcc[2]));
140 octe->buf[2] = ((plmn.mnc[2] << 4) | (plmn.mnc[1]));
144 /*******************************************************************
146 * @brief Fills the RicId
150 * Function : FillRicId
152 * Functionality: Fills the RicId
154 * @params[in] BIT_STRING_t *nbid,
159 * @return ROK - success
162 * ****************************************************************/
164 S16 FillRicId(BIT_STRING_t *id, U8 unusedBits, U8 byteSize, U8 val)
168 RIC_ALLOC(id->buf, id->size * sizeof(U8));
174 for (tmp = 0 ; tmp < (byteSize-1); tmp++)
178 id->buf[byteSize-1] = val; //change this
179 id->bits_unused = unusedBits;
183 /*******************************************************************
185 * @brief Builds Global RIC Id Params
189 * Function : BuildGlobalRicId
191 * Functionality: Building the Plmn and ric id
193 * @params[in] GlobalRIC_ID_t *ricId
194 * @return ROK - success
197 * ****************************************************************/
199 S16 BuildGlobalRicId(GlobalRIC_ID_t *ricId)
206 plmnBuildRic(cuCfgParams.plmn , &ricId->pLMN_Identity);
208 FillRicId(&ricId->ric_ID, unused, byteSize, val);
213 RANfunctionID_ItemIEs_t* FillRanFuncItems(RANfunctionID_ItemIEs_t *items)
217 items->id = ProtocolIE_IDE2_id_RANfunction_Item;
218 items->criticality = CriticalityE2_reject;
219 items->value.present = RANfunctionID_ItemIEs__value_PR_RANfunctionID_Item;
220 items->value.choice.RANfunctionID_Item.ranFunctionID = 1;
221 items->value.choice.RANfunctionID_Item.ranFunctionRevision = 4;
226 S16 BuildRANfuncIdList(RANfunctionsID_List_t *funcIdList)
229 RANfunctionID_ItemIEs_t *funcIdItems;
232 funcIdList->list.count = elementCnt;
233 funcIdList->list.size = elementCnt * sizeof(RANfunctionID_ItemIEs_t);
234 RIC_ALLOC(funcIdList->list.array, funcIdList->list.size);
235 if(funcIdList->list.array == NULLP)
237 DU_LOG("\nE2AP : Memory allocation for RAN Function List failed");
240 RIC_ALLOC(funcIdList->list.array[0], sizeof(RANfunctionID_ItemIEs_t));
241 FillRanFuncItems(funcIdList->list.array[0]);
246 /*******************************************************************
248 * @brief Builds and sends the E2SetupResponse
252 * Function : BuildAndSendE2SetupRsp
254 * Functionality: Constructs the F1SetupResponse message and sends
255 * it back to the DU through SCTP.
257 * @params[in] void **buf,Buffer to which encoded pattern is written into
258 * @params[in] int *size,size of buffer
260 * @return ROK - success
263 * ****************************************************************/
264 S16 BuildAndSendE2SetupRsp()
266 E2AP_PDU_t *e2apMsg = NULL;
267 E2setupResponse_t *e2SetupRsp;
268 asn_enc_rval_t encRetVal;
273 DU_LOG("\nE2AP : Building E2 Setup Response\n");
275 RIC_ALLOC(e2apMsg, sizeof(E2AP_PDU_t));
278 DU_LOG("\nE2AP : Memory allocation for E2AP-PDU failed");
281 e2apMsg->present = E2AP_PDU_PR_successfulOutcome;
282 RIC_ALLOC(e2apMsg->choice.successfulOutcome, sizeof(SuccessfulOutcomeE2_t));
283 if(e2apMsg->choice.successfulOutcome == NULLP)
285 DU_LOG("\nE2AP : Memory allocation for E2AP-PDU failed");
286 RIC_FREE(e2apMsg, sizeof(E2AP_PDU_t));
290 e2apMsg->choice.successfulOutcome->procedureCode = ProcedureCodeE2_id_E2setup;
291 e2apMsg->choice.successfulOutcome->criticality = CriticalityE2_reject;
292 e2apMsg->choice.successfulOutcome->value.present = \
293 SuccessfulOutcomeE2__value_PR_E2setupResponse;
294 e2SetupRsp = &e2apMsg->choice.successfulOutcome->value.choice.E2setupResponse;
297 e2SetupRsp->protocolIEs.list.count = elementCnt;
298 e2SetupRsp->protocolIEs.list.size = elementCnt * sizeof(E2setupResponseIEs_t);
300 RIC_ALLOC(e2SetupRsp->protocolIEs.list.array, \
301 e2SetupRsp->protocolIEs.list.size);
302 if(e2SetupRsp->protocolIEs.list.array == NULLP)
304 DU_LOG("\nE2AP : Memory allocation for E2ResponseIEs failed");
305 RIC_FREE(e2apMsg->choice.successfulOutcome, sizeof(SuccessfulOutcomeE2_t));
306 RIC_FREE(e2apMsg, sizeof(E2AP_PDU_t));
310 for(idx=0; idx<elementCnt; idx++)
312 RIC_ALLOC(e2SetupRsp->protocolIEs.list.array[idx], \
313 sizeof(E2setupResponseIEs_t));
314 if(e2SetupRsp->protocolIEs.list.array[idx] == NULLP)
316 RIC_FREE(e2SetupRsp->protocolIEs.list.array,\
317 e2SetupRsp->protocolIEs.list.size);
318 RIC_FREE(e2apMsg->choice.successfulOutcome, \
319 sizeof(SuccessfulOutcomeE2_t));
320 RIC_FREE(e2apMsg, sizeof(E2AP_PDU_t));
326 e2SetupRsp->protocolIEs.list.array[idx]->id = ProtocolIE_IDE2_id_GlobalRIC_ID;
327 e2SetupRsp->protocolIEs.list.array[idx]->criticality = CriticalityE2_reject;
328 e2SetupRsp->protocolIEs.list.array[idx]->value.present = \
329 E2setupResponseIEs__value_PR_GlobalRIC_ID;
331 BuildGlobalRicId(&(e2SetupRsp->protocolIEs.list.array[idx]->value.choice.GlobalRIC_ID));
333 xer_fprint(stdout, &asn_DEF_E2AP_PDU, e2apMsg);
334 cmMemset((U8 *)encBuf, 0, ENC_BUF_MAX_LEN);
336 encRetVal = aper_encode(&asn_DEF_E2AP_PDU, 0, e2apMsg, PrepFinalEncBuf, encBuf);
338 /* Check encode results */
339 if(encRetVal.encoded == ENCODE_FAIL)
341 DU_LOG("\nE2AP : Could not encode E2SetupResponse structure (at %s)\n",\
342 encRetVal.failed_type ? encRetVal.failed_type->name : "unknown");
347 DU_LOG("\nE2AP : Created APER encoded buffer for E2SetupResponse\n");
348 for(int i=0; i< encBufSize; i++)
350 printf("%x",encBuf[i]);
355 if(SendE2APMsg(RIC_APP_MEM_REG, RIC_POOL) != ROK)
357 DU_LOG("\nF1AP : Sending E2 Setup Response failed");
364 /*******************************************************************
366 * @brief Builds Ric Request Id
370 * Function : BuildRicRequestId
372 * Functionality: Building the Ric Request Id
374 * @params[in] RICrequestID_t *ricReqId
375 * @return ROK - success
378 * ****************************************************************/
380 S16 BuildRicRequestId(RICrequestID_t *ricReqId)
383 if(ricReqId != NULLP)
385 ricReqId->ricRequestorID = 1;
386 ricReqId->ricInstanceID = 1;
391 /*******************************************************************
393 * @brief Fills Ric Action To be Setup Item
397 * Function : fillSetupItems
399 * Functionality: Filling ricAction Id, RicActionType
401 * @params[in] RICaction_ToBeSetup_Item_t *setupItems
402 * @return pointer of type RICaction_ToBeSetup_Item_t
404 * ****************************************************************/
406 RICaction_ToBeSetup_Item_t* fillSetupItems(RICaction_ToBeSetup_Item_t *setupItems)
408 if(setupItems != NULLP)
410 setupItems->ricActionID = 0;
411 setupItems->ricActionType = RICactionType_report;
414 RETVALUE(setupItems);
417 /*******************************************************************
419 * @brief Fills RIC Subscription Details Item List
423 * Function : fillSubsDetails
425 * Functionality: Fill the RIC Subscription Details Items List
427 * @params[in] RICaction_ToBeSetup_ItemIEs_t *items
428 * @return ROK - success
431 * ****************************************************************/
433 S16 fillSubsDetails(RICaction_ToBeSetup_ItemIEs_t *items)
437 items->id = ProtocolIE_IDE2_id_RICaction_ToBeSetup_Item;
438 items->criticality = CriticalityE2_ignore;
439 items->value.present = RICaction_ToBeSetup_ItemIEs__value_PR_RICaction_ToBeSetup_Item;
440 fillSetupItems(&(items->value.choice.RICaction_ToBeSetup_Item));
445 /*******************************************************************
447 * @brief builds RIC Subscription Details
451 * Function : BuildsRicSubsDetails
453 * Functionality: Builds the RIC Subscription Details
455 * @params[in] RICsubscriptionDetails_t *subsDetails
456 * @return ROK - success
459 * ****************************************************************/
461 S16 BuildRicSubsDetails(RICsubscriptionDetails_t *subsDetails)
466 if(subsDetails != NULLP)
468 /* Plmn is not called */
469 plmnBuildRic(cuCfgParams.plmn, &subsDetails->ricEventTriggerDefinition);
471 subsDetails->ricAction_ToBeSetup_List.list.count = elementCnt;
472 subsDetails->ricAction_ToBeSetup_List.list.size = \
473 elementCnt * sizeof(RICaction_ToBeSetup_ItemIEs_t);
474 RIC_ALLOC(subsDetails->ricAction_ToBeSetup_List.list.array, \
475 subsDetails->ricAction_ToBeSetup_List.list.size);
476 if(subsDetails->ricAction_ToBeSetup_List.list.array == NULLP)
478 DU_LOG("\nE2AP : Memory allocation for RICactionToBeSetup Items failed");
481 RIC_ALLOC(subsDetails->ricAction_ToBeSetup_List.list.array[0],\
482 sizeof(RICaction_ToBeSetup_ItemIEs_t));
483 fillSubsDetails(subsDetails->ricAction_ToBeSetup_List.list.array[0]);
488 /*******************************************************************
490 * @brief Builds and Send the RicSubscriptionReq
494 * Function : BuildAndSendRicSubscriptionReq
496 * Functionality:Fills the RicSubscriptionReq
498 * @return ROK - success
501 ******************************************************************/
503 S16 BuildAndSendRicSubscriptionReq()
506 E2AP_PDU_t *e2apRicMsg = NULL;
507 RICsubscriptionRequest_t *ricSubscriptionReq;
512 asn_enc_rval_t encRetVal; /* Encoder return value */
513 ricSubsStatus = TRUE;
515 DU_LOG("\nE2AP : Building RIC Subscription Request\n");
517 RIC_ALLOC(e2apRicMsg, sizeof(E2AP_PDU_t));
518 if(e2apRicMsg == NULLP)
520 DU_LOG("\nE2AP : Memory allocation for E2AP-PDU failed");
524 e2apRicMsg->present = E2AP_PDU_PR_initiatingMessage;
525 RIC_ALLOC(e2apRicMsg->choice.initiatingMessage, sizeof(InitiatingMessageE2_t));
526 if(e2apRicMsg->choice.initiatingMessage == NULLP)
528 DU_LOG("\nE2AP : Memory allocation for E2AP-PDU failed");
529 RIC_FREE(e2apRicMsg, sizeof(E2AP_PDU_t));
532 e2apRicMsg->choice.initiatingMessage->procedureCode = ProcedureCodeE2_id_RICsubscription;
533 e2apRicMsg->choice.initiatingMessage->criticality = CriticalityE2_reject;
534 e2apRicMsg->choice.initiatingMessage->value.present = InitiatingMessageE2__value_PR_RICsubscriptionRequest;
536 RIC_ALLOC(ricSubscriptionReq, sizeof(RICsubscriptionRequest_t));
537 ricSubscriptionReq = &e2apRicMsg->choice.initiatingMessage->value.choice.RICsubscriptionRequest;
540 ricSubscriptionReq->protocolIEs.list.count = elementCnt;
541 ricSubscriptionReq->protocolIEs.list.size = elementCnt * sizeof(RICsubscriptionRequest_IEs_t);
543 /* Initialize the subscription members */
544 RIC_ALLOC(ricSubscriptionReq->protocolIEs.list.array, \
545 ricSubscriptionReq->protocolIEs.list.size);
546 if(ricSubscriptionReq->protocolIEs.list.array == NULLP)
548 DU_LOG("\nE2AP : Memory allocation for RICSubscriptionRequestIEs failed");
549 RIC_FREE(e2apRicMsg->choice.initiatingMessage, sizeof(InitiatingMessageE2_t));
550 RIC_FREE(e2apRicMsg, (Size)sizeof(E2AP_PDU_t));
554 for(idx=0; idx<elementCnt; idx++)
556 RIC_ALLOC(ricSubscriptionReq->protocolIEs.list.array[idx],\
557 sizeof(RICsubscriptionRequest_IEs_t));
558 if(ricSubscriptionReq->protocolIEs.list.array[idx] == NULLP)
560 for(ieId=0; ieId<idx; ieId++)
562 RIC_FREE(ricSubscriptionReq->protocolIEs.list.array[ieId],\
563 sizeof(RICsubscriptionRequest_IEs_t));
565 RIC_FREE(ricSubscriptionReq->protocolIEs.list.array,\
566 ricSubscriptionReq->protocolIEs.list.size);
567 RIC_FREE(e2apRicMsg->choice.initiatingMessage, \
568 sizeof(InitiatingMessageE2_t));
569 RIC_FREE(e2apRicMsg, sizeof(E2AP_PDU_t));
574 /* Filling RIC Request Id */
576 ricSubscriptionReq->protocolIEs.list.array[idx]->id = ProtocolIE_IDE2_id_RICrequestID;
577 ricSubscriptionReq->protocolIEs.list.array[idx]->criticality = CriticalityE2_reject;
578 ricSubscriptionReq->protocolIEs.list.array[idx]->value.present =\
579 RICsubscriptionRequest_IEs__value_PR_RICrequestID;
581 BuildRicRequestId(&ricSubscriptionReq->protocolIEs.list.array[idx]->value.choice.RICrequestID);
584 /* Filling RAN Function Id */
586 ricSubscriptionReq->protocolIEs.list.array[idx]->id = ProtocolIE_IDE2_id_RANfunctionID;
587 ricSubscriptionReq->protocolIEs.list.array[idx]->criticality = CriticalityE2_reject;
588 ricSubscriptionReq->protocolIEs.list.array[idx]->value.present =\
589 RICsubscriptionRequest_IEs__value_PR_RANfunctionID;
590 ricSubscriptionReq->protocolIEs.list.array[idx]->value.choice.RANfunctionID = 1;
593 /* Filling RIC Subscription Details */
595 ricSubscriptionReq->protocolIEs.list.array[idx]->id = ProtocolIE_IDE2_id_RICsubscriptionDetails;
596 ricSubscriptionReq->protocolIEs.list.array[idx]->criticality = CriticalityE2_reject;
597 ricSubscriptionReq->protocolIEs.list.array[idx]->value.present =\
598 RICsubscriptionRequest_IEs__value_PR_RICsubscriptionDetails;
600 BuildRicSubsDetails(&(ricSubscriptionReq->protocolIEs.list.array[idx]->value.choice.RICsubscriptionDetails));
603 /* Prints the Msg formed */
604 xer_fprint(stdout, &asn_DEF_E2AP_PDU, e2apRicMsg);
606 cmMemset((U8 *)encBuf, 0, ENC_BUF_MAX_LEN);
608 encRetVal = aper_encode(&asn_DEF_E2AP_PDU, 0, e2apRicMsg, PrepFinalEncBuf,\
610 if(encRetVal.encoded == ENCODE_FAIL)
612 DU_LOG("\nE2AP : Could not encode RicSubscriptionRequest structure (at %s)\n",\
613 encRetVal.failed_type ? encRetVal.failed_type->name : "unknown");
618 DU_LOG("\nE2AP : Created APER encoded buffer for RicSubscriptionRequest\n");
619 for(int i=0; i< encBufSize; i++)
621 printf("%x",encBuf[i]);
627 if(SendE2APMsg(RIC_APP_MEM_REG, RIC_POOL) != ROK)
629 DU_LOG("\nE2AP : Sending RIC subscription Request failed");
637 /*******************************************************************
639 * @brief Handles received E2AP message and sends back response
643 * Function : E2APMsgHdlr
646 * - Decodes received E2AP control message
647 * - Prepares response message, encodes and sends to SCTP
650 * @return ROK - success
653 * ****************************************************************/
654 void E2APMsgHdlr(Buffer *mBuf)
661 asn_dec_rval_t rval; /* Decoder return value */
662 E2AP_PDU_t e2apasnmsg ;
664 DU_LOG("\nE2AP : Received E2AP message buffer");
667 /* Copy mBuf into char array to decode it */
668 SFndLenMsg(mBuf, &recvBufLen);
669 if(SGetSBuf(DFLT_REGION, DFLT_POOL, (Data **)&recvBuf, (Size)recvBufLen) != ROK)
671 DU_LOG("\nE2AP : Memory allocation failed");
674 if(SCpyMsgFix(mBuf, 0, recvBufLen, (Data *)recvBuf, ©Cnt) != ROK)
676 DU_LOG("\nE2AP : Failed while copying %d", copyCnt);
680 printf("\nE2AP : Received flat buffer to be decoded : ");
681 for(i=0; i< recvBufLen; i++)
683 printf("%x",recvBuf[i]);
686 /* Decoding flat buffer into F1AP messsage */
687 e2apMsg = &e2apasnmsg;
688 memset(e2apMsg, 0, sizeof(E2AP_PDU_t));
690 rval = aper_decode(0, &asn_DEF_E2AP_PDU, (void **)&e2apMsg, recvBuf, recvBufLen, 0, 0);
691 SPutSBuf(DFLT_REGION, DFLT_POOL, (Data *)recvBuf, (Size)recvBufLen);
692 if(rval.code == RC_FAIL || rval.code == RC_WMORE)
694 DU_LOG("\nE2AP : ASN decode failed");
698 xer_fprint(stdout, &asn_DEF_E2AP_PDU, e2apMsg);
700 switch(e2apMsg->present)
702 case E2AP_PDU_PR_initiatingMessage:
704 switch(e2apMsg->choice.initiatingMessage->value.present)
706 case InitiatingMessageE2__value_PR_E2setupRequest:
708 DU_LOG("\nE2AP : E2 setup request received");
709 BuildAndSendE2SetupRsp();
712 case InitiatingMessageE2__value_PR_RICindication:
714 DU_LOG("\nE2AP : RIC Indication Acknowledged");
719 DU_LOG("\nE2AP : Invalid type of intiating message [%d]",e2apMsg->choice.initiatingMessage->value.present);
722 }/* End of switch(initiatingMessage) */
725 case E2AP_PDU_PR_successfulOutcome:
727 switch(e2apMsg->choice.successfulOutcome->value.present)
729 case SuccessfulOutcomeE2__value_PR_RICsubscriptionResponse:
731 DU_LOG("\nE2AP : RICsubscriptionResponse Msg Acknowledged");
736 DU_LOG("\nE2AP : Invalid type of successfulOutcome message [%d]",e2apMsg->choice.successfulOutcome->value.present);
745 DU_LOG("\nE2AP : Invalid type message type ");
749 }/* End of switch(e2apMsg->present) */
752 BuildAndSendRicSubscriptionReq();
754 } /* End of E2APMsgHdlr */
757 /**********************************************************************
759 **********************************************************************/