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 "odu_common_codec.h"
23 #include "ric_stub_sctp.h"
24 #include "ric_e2ap_msg_hdl.h"
25 #include "GlobalE2node-gNB-ID.h"
26 #include "ProtocolIE-FieldE2.h"
32 /*******************************************************************
34 * @brief Sends E2 msg over SCTP
38 * Function : SendE2APMsg
40 * Functionality: Sends E2 msg over SCTP
42 * @params[in] Region region
44 * @return ROK - success
47 * ****************************************************************/
49 S16 SendE2APMsg(Region region, Pool pool)
53 if(SGetMsg(region, pool, &mBuf) == ROK)
55 if(SAddPstMsgMult((Data *)encBuf, encBufSize, mBuf) == ROK)
59 if(sctpSend(mBuf) != ROK)
61 DU_LOG("\nE2AP : SCTP Send for E2 failed");
68 DU_LOG("\nE2AP : SAddPstMsgMult failed");
76 DU_LOG("\nE2AP : Failed to allocate memory");
83 /*******************************************************************
85 * @brief Builds Global RIC Id Params
89 * Function : BuildGlobalRicId
91 * Functionality: Building the Plmn and ric id
93 * @params[in] GlobalRIC_ID_t *ricId
94 * @return ROK - success
97 * ****************************************************************/
99 S16 BuildGlobalRicId(GlobalRIC_ID_t *ricId)
106 ricId->pLMN_Identity.size = byteSize * sizeof(U8);
107 RIC_ALLOC(ricId->pLMN_Identity.buf, ricId->pLMN_Identity.size);
108 buildPlmnId(ricCfgParams.plmn , &ricId->pLMN_Identity);
110 ricId->ric_ID.size = byteSize * sizeof(U8);
111 RIC_ALLOC(ricId->ric_ID.buf, ricId->ric_ID.size);
112 fillBitString(&ricId->ric_ID, unused, byteSize, val);
117 /*******************************************************************
119 * @brief Builds and sends the E2SetupResponse
123 * Function : BuildAndSendE2SetupRsp
125 * Functionality: Constructs the F1SetupResponse message and sends
126 * it back to the DU through SCTP.
128 * @params[in] void **buf,Buffer to which encoded pattern is written into
129 * @params[in] int *size,size of buffer
131 * @return ROK - success
134 * ****************************************************************/
135 S16 BuildAndSendE2SetupRsp()
137 E2AP_PDU_t *e2apMsg = NULL;
138 E2setupResponse_t *e2SetupRsp;
139 asn_enc_rval_t encRetVal;
144 DU_LOG("\nE2AP : Building E2 Setup Response\n");
146 RIC_ALLOC(e2apMsg, sizeof(E2AP_PDU_t));
149 DU_LOG("\nE2AP : Memory allocation for E2AP-PDU failed");
152 e2apMsg->present = E2AP_PDU_PR_successfulOutcome;
153 RIC_ALLOC(e2apMsg->choice.successfulOutcome, sizeof(SuccessfulOutcomeE2_t));
154 if(e2apMsg->choice.successfulOutcome == NULLP)
156 DU_LOG("\nE2AP : Memory allocation for E2AP-PDU failed");
157 RIC_FREE(e2apMsg, sizeof(E2AP_PDU_t));
161 e2apMsg->choice.successfulOutcome->procedureCode = ProcedureCodeE2_id_E2setup;
162 e2apMsg->choice.successfulOutcome->criticality = CriticalityE2_reject;
163 e2apMsg->choice.successfulOutcome->value.present = \
164 SuccessfulOutcomeE2__value_PR_E2setupResponse;
165 e2SetupRsp = &e2apMsg->choice.successfulOutcome->value.choice.E2setupResponse;
168 e2SetupRsp->protocolIEs.list.count = elementCnt;
169 e2SetupRsp->protocolIEs.list.size = elementCnt * sizeof(E2setupResponseIEs_t);
171 RIC_ALLOC(e2SetupRsp->protocolIEs.list.array, \
172 e2SetupRsp->protocolIEs.list.size);
173 if(e2SetupRsp->protocolIEs.list.array == NULLP)
175 DU_LOG("\nE2AP : Memory allocation for E2ResponseIEs failed");
176 RIC_FREE(e2apMsg->choice.successfulOutcome, sizeof(SuccessfulOutcomeE2_t));
177 RIC_FREE(e2apMsg, sizeof(E2AP_PDU_t));
181 for(idx=0; idx<elementCnt; idx++)
183 RIC_ALLOC(e2SetupRsp->protocolIEs.list.array[idx], \
184 sizeof(E2setupResponseIEs_t));
185 if(e2SetupRsp->protocolIEs.list.array[idx] == NULLP)
187 RIC_FREE(e2SetupRsp->protocolIEs.list.array,\
188 e2SetupRsp->protocolIEs.list.size);
189 RIC_FREE(e2apMsg->choice.successfulOutcome, \
190 sizeof(SuccessfulOutcomeE2_t));
191 RIC_FREE(e2apMsg, sizeof(E2AP_PDU_t));
197 e2SetupRsp->protocolIEs.list.array[idx]->id = ProtocolIE_IDE2_id_GlobalRIC_ID;
198 e2SetupRsp->protocolIEs.list.array[idx]->criticality = CriticalityE2_reject;
199 e2SetupRsp->protocolIEs.list.array[idx]->value.present = \
200 E2setupResponseIEs__value_PR_GlobalRIC_ID;
202 BuildGlobalRicId(&(e2SetupRsp->protocolIEs.list.array[idx]->value.choice.GlobalRIC_ID));
204 xer_fprint(stdout, &asn_DEF_E2AP_PDU, e2apMsg);
205 cmMemset((U8 *)encBuf, 0, ENC_BUF_MAX_LEN);
207 encRetVal = aper_encode(&asn_DEF_E2AP_PDU, 0, e2apMsg, PrepFinalEncBuf, encBuf);
209 /* Check encode results */
210 if(encRetVal.encoded == ENCODE_FAIL)
212 DU_LOG("\nE2AP : Could not encode E2SetupResponse structure (at %s)\n",\
213 encRetVal.failed_type ? encRetVal.failed_type->name : "unknown");
218 DU_LOG("\nE2AP : Created APER encoded buffer for E2SetupResponse\n");
219 for(int i=0; i< encBufSize; i++)
221 printf("%x",encBuf[i]);
226 if(SendE2APMsg(RIC_APP_MEM_REG, RIC_POOL) != ROK)
228 DU_LOG("\nE2AP : Sending E2 Setup Response failed");
235 /*******************************************************************
237 * @brief Builds Ric Request Id
241 * Function : BuildRicRequestId
243 * Functionality: Building the Ric Request Id
245 * @params[in] RICrequestID_t *ricReqId
246 * @return ROK - success
249 * ****************************************************************/
251 S16 BuildRicRequestId(RICrequestID_t *ricReqId)
254 if(ricReqId != NULLP)
256 ricReqId->ricRequestorID = 1;
257 ricReqId->ricInstanceID = 1;
262 /*******************************************************************
264 * @brief Fills Ric Action To be Setup Item
268 * Function : fillSetupItems
270 * Functionality: Filling ricAction Id, RicActionType
272 * @params[in] RICaction_ToBeSetup_Item_t *setupItems
273 * @return pointer of type RICaction_ToBeSetup_Item_t
275 * ****************************************************************/
277 RICaction_ToBeSetup_Item_t* fillSetupItems(RICaction_ToBeSetup_Item_t *setupItems)
279 if(setupItems != NULLP)
281 setupItems->ricActionID = 0;
282 setupItems->ricActionType = RICactionType_report;
285 RETVALUE(setupItems);
288 /*******************************************************************
290 * @brief Fills RIC Subscription Details Item List
294 * Function : fillSubsDetails
296 * Functionality: Fill the RIC Subscription Details Items List
298 * @params[in] RICaction_ToBeSetup_ItemIEs_t *items
299 * @return ROK - success
302 * ****************************************************************/
304 S16 fillSubsDetails(RICaction_ToBeSetup_ItemIEs_t *items)
308 items->id = ProtocolIE_IDE2_id_RICaction_ToBeSetup_Item;
309 items->criticality = CriticalityE2_ignore;
310 items->value.present = RICaction_ToBeSetup_ItemIEs__value_PR_RICaction_ToBeSetup_Item;
311 fillSetupItems(&(items->value.choice.RICaction_ToBeSetup_Item));
316 /*******************************************************************
318 * @brief builds RIC Subscription Details
322 * Function : BuildsRicSubsDetails
324 * Functionality: Builds the RIC Subscription Details
326 * @params[in] RICsubscriptionDetails_t *subsDetails
327 * @return ROK - success
330 * ****************************************************************/
332 S16 BuildRicSubsDetails(RICsubscriptionDetails_t *subsDetails)
337 if(subsDetails != NULLP)
339 /* Octet string to be build here */
340 /* Sending PLMN as Octect string */
342 subsDetails->ricEventTriggerDefinition.size = byteSize * sizeof(U8);
343 RIC_ALLOC(subsDetails->ricEventTriggerDefinition.buf, subsDetails->ricEventTriggerDefinition.size);
344 buildPlmnId(ricCfgParams.plmn, &subsDetails->ricEventTriggerDefinition);
346 subsDetails->ricAction_ToBeSetup_List.list.count = elementCnt;
347 subsDetails->ricAction_ToBeSetup_List.list.size = \
348 elementCnt * sizeof(RICaction_ToBeSetup_ItemIEs_t);
349 RIC_ALLOC(subsDetails->ricAction_ToBeSetup_List.list.array, \
350 subsDetails->ricAction_ToBeSetup_List.list.size);
351 if(subsDetails->ricAction_ToBeSetup_List.list.array == NULLP)
353 DU_LOG("\nE2AP : Memory allocation for RICactionToBeSetup Items failed");
356 RIC_ALLOC(subsDetails->ricAction_ToBeSetup_List.list.array[0],\
357 sizeof(RICaction_ToBeSetup_ItemIEs_t));
358 fillSubsDetails(subsDetails->ricAction_ToBeSetup_List.list.array[0]);
363 /*******************************************************************
365 * @brief Builds and Send the RicSubscriptionReq
369 * Function : BuildAndSendRicSubscriptionReq
371 * Functionality:Fills the RicSubscriptionReq
373 * @return ROK - success
376 ******************************************************************/
378 S16 BuildAndSendRicSubscriptionReq()
381 E2AP_PDU_t *e2apRicMsg = NULL;
382 RICsubscriptionRequest_t *ricSubscriptionReq;
387 asn_enc_rval_t encRetVal; /* Encoder return value */
388 ricSubsStatus = TRUE;
390 DU_LOG("\nE2AP : Building RIC Subscription Request\n");
392 RIC_ALLOC(e2apRicMsg, sizeof(E2AP_PDU_t));
393 if(e2apRicMsg == NULLP)
395 DU_LOG("\nE2AP : Memory allocation for E2AP-PDU failed");
399 e2apRicMsg->present = E2AP_PDU_PR_initiatingMessage;
400 RIC_ALLOC(e2apRicMsg->choice.initiatingMessage, sizeof(InitiatingMessageE2_t));
401 if(e2apRicMsg->choice.initiatingMessage == NULLP)
403 DU_LOG("\nE2AP : Memory allocation for E2AP-PDU failed");
404 RIC_FREE(e2apRicMsg, sizeof(E2AP_PDU_t));
407 e2apRicMsg->choice.initiatingMessage->procedureCode = ProcedureCodeE2_id_RICsubscription;
408 e2apRicMsg->choice.initiatingMessage->criticality = CriticalityE2_reject;
409 e2apRicMsg->choice.initiatingMessage->value.present = InitiatingMessageE2__value_PR_RICsubscriptionRequest;
411 RIC_ALLOC(ricSubscriptionReq, sizeof(RICsubscriptionRequest_t));
412 ricSubscriptionReq = &e2apRicMsg->choice.initiatingMessage->value.choice.RICsubscriptionRequest;
415 ricSubscriptionReq->protocolIEs.list.count = elementCnt;
416 ricSubscriptionReq->protocolIEs.list.size = elementCnt * sizeof(RICsubscriptionRequest_IEs_t);
418 /* Initialize the subscription members */
419 RIC_ALLOC(ricSubscriptionReq->protocolIEs.list.array, \
420 ricSubscriptionReq->protocolIEs.list.size);
421 if(ricSubscriptionReq->protocolIEs.list.array == NULLP)
423 DU_LOG("\nE2AP : Memory allocation for RICSubscriptionRequestIEs failed");
424 RIC_FREE(e2apRicMsg->choice.initiatingMessage, sizeof(InitiatingMessageE2_t));
425 RIC_FREE(e2apRicMsg, (Size)sizeof(E2AP_PDU_t));
429 for(idx=0; idx<elementCnt; idx++)
431 RIC_ALLOC(ricSubscriptionReq->protocolIEs.list.array[idx],\
432 sizeof(RICsubscriptionRequest_IEs_t));
433 if(ricSubscriptionReq->protocolIEs.list.array[idx] == NULLP)
435 for(ieId=0; ieId<idx; ieId++)
437 RIC_FREE(ricSubscriptionReq->protocolIEs.list.array[ieId],\
438 sizeof(RICsubscriptionRequest_IEs_t));
440 RIC_FREE(ricSubscriptionReq->protocolIEs.list.array,\
441 ricSubscriptionReq->protocolIEs.list.size);
442 RIC_FREE(e2apRicMsg->choice.initiatingMessage, \
443 sizeof(InitiatingMessageE2_t));
444 RIC_FREE(e2apRicMsg, sizeof(E2AP_PDU_t));
449 /* Filling RIC Request Id */
451 ricSubscriptionReq->protocolIEs.list.array[idx]->id = ProtocolIE_IDE2_id_RICrequestID;
452 ricSubscriptionReq->protocolIEs.list.array[idx]->criticality = CriticalityE2_reject;
453 ricSubscriptionReq->protocolIEs.list.array[idx]->value.present =\
454 RICsubscriptionRequest_IEs__value_PR_RICrequestID;
456 BuildRicRequestId(&ricSubscriptionReq->protocolIEs.list.array[idx]->value.choice.RICrequestID);
459 /* Filling RAN Function Id */
461 ricSubscriptionReq->protocolIEs.list.array[idx]->id = ProtocolIE_IDE2_id_RANfunctionID;
462 ricSubscriptionReq->protocolIEs.list.array[idx]->criticality = CriticalityE2_reject;
463 ricSubscriptionReq->protocolIEs.list.array[idx]->value.present =\
464 RICsubscriptionRequest_IEs__value_PR_RANfunctionID;
465 ricSubscriptionReq->protocolIEs.list.array[idx]->value.choice.RANfunctionID = 1;
468 /* Filling RIC Subscription Details */
470 ricSubscriptionReq->protocolIEs.list.array[idx]->id = ProtocolIE_IDE2_id_RICsubscriptionDetails;
471 ricSubscriptionReq->protocolIEs.list.array[idx]->criticality = CriticalityE2_reject;
472 ricSubscriptionReq->protocolIEs.list.array[idx]->value.present =\
473 RICsubscriptionRequest_IEs__value_PR_RICsubscriptionDetails;
475 BuildRicSubsDetails(&(ricSubscriptionReq->protocolIEs.list.array[idx]->value.choice.RICsubscriptionDetails));
478 /* Prints the Msg formed */
479 xer_fprint(stdout, &asn_DEF_E2AP_PDU, e2apRicMsg);
481 cmMemset((U8 *)encBuf, 0, ENC_BUF_MAX_LEN);
483 encRetVal = aper_encode(&asn_DEF_E2AP_PDU, 0, e2apRicMsg, PrepFinalEncBuf,\
485 if(encRetVal.encoded == ENCODE_FAIL)
487 DU_LOG("\nE2AP : Could not encode RicSubscriptionRequest structure (at %s)\n",\
488 encRetVal.failed_type ? encRetVal.failed_type->name : "unknown");
493 DU_LOG("\nE2AP : Created APER encoded buffer for RicSubscriptionRequest\n");
494 for(int i=0; i< encBufSize; i++)
496 printf("%x",encBuf[i]);
502 if(SendE2APMsg(RIC_APP_MEM_REG, RIC_POOL) != ROK)
504 DU_LOG("\nE2AP : Sending RIC subscription Request failed");
512 /*******************************************************************
514 * @brief Handles received E2AP message and sends back response
518 * Function : E2APMsgHdlr
521 * - Decodes received E2AP control message
522 * - Prepares response message, encodes and sends to SCTP
525 * @return ROK - success
528 * ****************************************************************/
529 void E2APMsgHdlr(Buffer *mBuf)
536 asn_dec_rval_t rval; /* Decoder return value */
537 E2AP_PDU_t e2apasnmsg ;
539 DU_LOG("\nE2AP : Received E2AP message buffer");
542 /* Copy mBuf into char array to decode it */
543 SFndLenMsg(mBuf, &recvBufLen);
544 if(SGetSBuf(DFLT_REGION, DFLT_POOL, (Data **)&recvBuf, (Size)recvBufLen) != ROK)
546 DU_LOG("\nE2AP : Memory allocation failed");
549 if(SCpyMsgFix(mBuf, 0, recvBufLen, (Data *)recvBuf, ©Cnt) != ROK)
551 DU_LOG("\nE2AP : Failed while copying %d", copyCnt);
555 printf("\nE2AP : Received flat buffer to be decoded : ");
556 for(i=0; i< recvBufLen; i++)
558 printf("%x",recvBuf[i]);
561 /* Decoding flat buffer into E2AP messsage */
562 e2apMsg = &e2apasnmsg;
563 memset(e2apMsg, 0, sizeof(E2AP_PDU_t));
565 rval = aper_decode(0, &asn_DEF_E2AP_PDU, (void **)&e2apMsg, recvBuf, recvBufLen, 0, 0);
566 SPutSBuf(DFLT_REGION, DFLT_POOL, (Data *)recvBuf, (Size)recvBufLen);
567 if(rval.code == RC_FAIL || rval.code == RC_WMORE)
569 DU_LOG("\nE2AP : ASN decode failed");
573 xer_fprint(stdout, &asn_DEF_E2AP_PDU, e2apMsg);
575 switch(e2apMsg->present)
577 case E2AP_PDU_PR_initiatingMessage:
579 switch(e2apMsg->choice.initiatingMessage->value.present)
581 case InitiatingMessageE2__value_PR_E2setupRequest:
583 DU_LOG("\nE2AP : E2 setup request received");
584 BuildAndSendE2SetupRsp();
587 case InitiatingMessageE2__value_PR_RICindication:
589 DU_LOG("\nE2AP : RIC Indication Acknowledged");
594 DU_LOG("\nE2AP : Invalid type of intiating message [%d]",e2apMsg->choice.initiatingMessage->value.present);
597 }/* End of switch(initiatingMessage) */
600 case E2AP_PDU_PR_successfulOutcome:
602 switch(e2apMsg->choice.successfulOutcome->value.present)
604 case SuccessfulOutcomeE2__value_PR_RICsubscriptionResponse:
606 DU_LOG("\nE2AP : RICsubscriptionResponse Msg Acknowledged");
611 DU_LOG("\nE2AP : Invalid type of successfulOutcome message [%d]",e2apMsg->choice.successfulOutcome->value.present);
620 DU_LOG("\nE2AP : Invalid type message type ");
624 }/* End of switch(e2apMsg->present) */
627 BuildAndSendRicSubscriptionReq();
629 } /* End of E2APMsgHdlr */
632 /**********************************************************************
634 **********************************************************************/