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"
24 #include "odu_common_codec.h"
28 /*******************************************************************
30 * @brief Sends E2 msg over SCTP
34 * Function : SendE2APMsg
36 * Functionality: Sends E2 msg over SCTP
38 * @params[in] Region region
40 * @return ROK - success
43 * ****************************************************************/
45 S16 SendE2APMsg(Region region, Pool pool)
49 if(SGetMsg(region, pool, &mBuf) == ROK)
51 if(SAddPstMsgMult((Data *)encBuf, encBufSize, mBuf) == ROK)
55 if(sctpSend(mBuf) != ROK)
57 DU_LOG("\nE2AP : SCTP Send for E2 failed");
64 DU_LOG("\nE2AP : SAddPstMsgMult failed");
72 DU_LOG("\nE2AP : Failed to allocate memory");
79 /*******************************************************************
81 * @brief Builds Global RIC Id Params
85 * Function : BuildGlobalRicId
87 * Functionality: Building the Plmn and ric id
89 * @params[in] GlobalRIC_ID_t *ricId
90 * @return ROK - success
93 * ****************************************************************/
95 S16 BuildGlobalRicId(GlobalRIC_ID_t *ricId)
102 ricId->pLMN_Identity.size = byteSize * sizeof(U8);
103 RIC_ALLOC(ricId->pLMN_Identity.buf, ricId->pLMN_Identity.size);
104 buildPlmnId(ricCfgParams.plmn , &ricId->pLMN_Identity);
106 ricId->ric_ID.size = byteSize * sizeof(U8);
107 RIC_ALLOC(ricId->ric_ID.buf, ricId->ric_ID.size);
108 fillBitString(&ricId->ric_ID, unused, byteSize, val);
113 /*******************************************************************
115 * @brief Builds and sends the E2SetupResponse
119 * Function : BuildAndSendE2SetupRsp
121 * Functionality: Constructs the F1SetupResponse message and sends
122 * it back to the DU through SCTP.
124 * @params[in] void **buf,Buffer to which encoded pattern is written into
125 * @params[in] int *size,size of buffer
127 * @return ROK - success
130 * ****************************************************************/
131 S16 BuildAndSendE2SetupRsp()
133 E2AP_PDU_t *e2apMsg = NULL;
134 E2setupResponse_t *e2SetupRsp;
135 asn_enc_rval_t encRetVal;
140 DU_LOG("\nE2AP : Building E2 Setup Response\n");
142 RIC_ALLOC(e2apMsg, sizeof(E2AP_PDU_t));
145 DU_LOG("\nE2AP : Memory allocation for E2AP-PDU failed");
148 e2apMsg->present = E2AP_PDU_PR_successfulOutcome;
149 RIC_ALLOC(e2apMsg->choice.successfulOutcome, sizeof(SuccessfulOutcomeE2_t));
150 if(e2apMsg->choice.successfulOutcome == NULLP)
152 DU_LOG("\nE2AP : Memory allocation for E2AP-PDU failed");
153 RIC_FREE(e2apMsg, sizeof(E2AP_PDU_t));
157 e2apMsg->choice.successfulOutcome->procedureCode = ProcedureCodeE2_id_E2setup;
158 e2apMsg->choice.successfulOutcome->criticality = CriticalityE2_reject;
159 e2apMsg->choice.successfulOutcome->value.present = \
160 SuccessfulOutcomeE2__value_PR_E2setupResponse;
161 e2SetupRsp = &e2apMsg->choice.successfulOutcome->value.choice.E2setupResponse;
164 e2SetupRsp->protocolIEs.list.count = elementCnt;
165 e2SetupRsp->protocolIEs.list.size = elementCnt * sizeof(E2setupResponseIEs_t);
167 RIC_ALLOC(e2SetupRsp->protocolIEs.list.array, \
168 e2SetupRsp->protocolIEs.list.size);
169 if(e2SetupRsp->protocolIEs.list.array == NULLP)
171 DU_LOG("\nE2AP : Memory allocation for E2ResponseIEs failed");
172 RIC_FREE(e2apMsg->choice.successfulOutcome, sizeof(SuccessfulOutcomeE2_t));
173 RIC_FREE(e2apMsg, sizeof(E2AP_PDU_t));
177 for(idx=0; idx<elementCnt; idx++)
179 RIC_ALLOC(e2SetupRsp->protocolIEs.list.array[idx], \
180 sizeof(E2setupResponseIEs_t));
181 if(e2SetupRsp->protocolIEs.list.array[idx] == NULLP)
183 RIC_FREE(e2SetupRsp->protocolIEs.list.array,\
184 e2SetupRsp->protocolIEs.list.size);
185 RIC_FREE(e2apMsg->choice.successfulOutcome, \
186 sizeof(SuccessfulOutcomeE2_t));
187 RIC_FREE(e2apMsg, sizeof(E2AP_PDU_t));
193 e2SetupRsp->protocolIEs.list.array[idx]->id = ProtocolIE_IDE2_id_GlobalRIC_ID;
194 e2SetupRsp->protocolIEs.list.array[idx]->criticality = CriticalityE2_reject;
195 e2SetupRsp->protocolIEs.list.array[idx]->value.present = \
196 E2setupResponseIEs__value_PR_GlobalRIC_ID;
198 BuildGlobalRicId(&(e2SetupRsp->protocolIEs.list.array[idx]->value.choice.GlobalRIC_ID));
200 xer_fprint(stdout, &asn_DEF_E2AP_PDU, e2apMsg);
201 cmMemset((U8 *)encBuf, 0, ENC_BUF_MAX_LEN);
203 encRetVal = aper_encode(&asn_DEF_E2AP_PDU, 0, e2apMsg, PrepFinalEncBuf, encBuf);
205 /* Check encode results */
206 if(encRetVal.encoded == ENCODE_FAIL)
208 DU_LOG("\nE2AP : Could not encode E2SetupResponse structure (at %s)\n",\
209 encRetVal.failed_type ? encRetVal.failed_type->name : "unknown");
214 DU_LOG("\nE2AP : Created APER encoded buffer for E2SetupResponse\n");
215 for(int i=0; i< encBufSize; i++)
217 printf("%x",encBuf[i]);
222 if(SendE2APMsg(RIC_APP_MEM_REG, RIC_POOL) != ROK)
224 DU_LOG("\nE2AP : Sending E2 Setup Response failed");
231 /*******************************************************************
233 * @brief Builds Ric Request Id
237 * Function : BuildRicRequestId
239 * Functionality: Building the Ric Request Id
241 * @params[in] RICrequestID_t *ricReqId
242 * @return ROK - success
245 * ****************************************************************/
247 S16 BuildRicRequestId(RICrequestID_t *ricReqId)
250 if(ricReqId != NULLP)
252 ricReqId->ricRequestorID = 1;
253 ricReqId->ricInstanceID = 1;
258 /*******************************************************************
260 * @brief Fills Ric Action To be Setup Item
264 * Function : fillSetupItems
266 * Functionality: Filling ricAction Id, RicActionType
268 * @params[in] RICaction_ToBeSetup_Item_t *setupItems
269 * @return pointer of type RICaction_ToBeSetup_Item_t
271 * ****************************************************************/
273 RICaction_ToBeSetup_Item_t* fillSetupItems(RICaction_ToBeSetup_Item_t *setupItems)
275 if(setupItems != NULLP)
277 setupItems->ricActionID = 0;
278 setupItems->ricActionType = RICactionType_report;
281 RETVALUE(setupItems);
284 /*******************************************************************
286 * @brief Fills RIC Subscription Details Item List
290 * Function : fillSubsDetails
292 * Functionality: Fill the RIC Subscription Details Items List
294 * @params[in] RICaction_ToBeSetup_ItemIEs_t *items
295 * @return ROK - success
298 * ****************************************************************/
300 S16 fillSubsDetails(RICaction_ToBeSetup_ItemIEs_t *items)
304 items->id = ProtocolIE_IDE2_id_RICaction_ToBeSetup_Item;
305 items->criticality = CriticalityE2_ignore;
306 items->value.present = RICaction_ToBeSetup_ItemIEs__value_PR_RICaction_ToBeSetup_Item;
307 fillSetupItems(&(items->value.choice.RICaction_ToBeSetup_Item));
312 /*******************************************************************
314 * @brief builds RIC Subscription Details
318 * Function : BuildsRicSubsDetails
320 * Functionality: Builds the RIC Subscription Details
322 * @params[in] RICsubscriptionDetails_t *subsDetails
323 * @return ROK - success
326 * ****************************************************************/
328 S16 BuildRicSubsDetails(RICsubscriptionDetails_t *subsDetails)
333 if(subsDetails != NULLP)
335 /* Octet string to be build here */
336 /* Sending PLMN as Octect string */
338 subsDetails->ricEventTriggerDefinition.size = byteSize * sizeof(U8);
339 RIC_ALLOC(subsDetails->ricEventTriggerDefinition.buf, subsDetails->ricEventTriggerDefinition.size);
340 buildPlmnId(ricCfgParams.plmn, &subsDetails->ricEventTriggerDefinition);
342 subsDetails->ricAction_ToBeSetup_List.list.count = elementCnt;
343 subsDetails->ricAction_ToBeSetup_List.list.size = \
344 elementCnt * sizeof(RICaction_ToBeSetup_ItemIEs_t);
345 RIC_ALLOC(subsDetails->ricAction_ToBeSetup_List.list.array, \
346 subsDetails->ricAction_ToBeSetup_List.list.size);
347 if(subsDetails->ricAction_ToBeSetup_List.list.array == NULLP)
349 DU_LOG("\nE2AP : Memory allocation for RICactionToBeSetup Items failed");
352 RIC_ALLOC(subsDetails->ricAction_ToBeSetup_List.list.array[0],\
353 sizeof(RICaction_ToBeSetup_ItemIEs_t));
354 fillSubsDetails(subsDetails->ricAction_ToBeSetup_List.list.array[0]);
359 /*******************************************************************
361 * @brief Builds and Send the RicSubscriptionReq
365 * Function : BuildAndSendRicSubscriptionReq
367 * Functionality:Fills the RicSubscriptionReq
369 * @return ROK - success
372 ******************************************************************/
374 S16 BuildAndSendRicSubscriptionReq()
377 E2AP_PDU_t *e2apRicMsg = NULL;
378 RICsubscriptionRequest_t *ricSubscriptionReq;
383 asn_enc_rval_t encRetVal; /* Encoder return value */
384 ricSubsStatus = TRUE;
386 DU_LOG("\nE2AP : Building RIC Subscription Request\n");
388 RIC_ALLOC(e2apRicMsg, sizeof(E2AP_PDU_t));
389 if(e2apRicMsg == NULLP)
391 DU_LOG("\nE2AP : Memory allocation for E2AP-PDU failed");
395 e2apRicMsg->present = E2AP_PDU_PR_initiatingMessage;
396 RIC_ALLOC(e2apRicMsg->choice.initiatingMessage, sizeof(InitiatingMessageE2_t));
397 if(e2apRicMsg->choice.initiatingMessage == NULLP)
399 DU_LOG("\nE2AP : Memory allocation for E2AP-PDU failed");
400 RIC_FREE(e2apRicMsg, sizeof(E2AP_PDU_t));
403 e2apRicMsg->choice.initiatingMessage->procedureCode = ProcedureCodeE2_id_RICsubscription;
404 e2apRicMsg->choice.initiatingMessage->criticality = CriticalityE2_reject;
405 e2apRicMsg->choice.initiatingMessage->value.present = InitiatingMessageE2__value_PR_RICsubscriptionRequest;
407 RIC_ALLOC(ricSubscriptionReq, sizeof(RICsubscriptionRequest_t));
408 ricSubscriptionReq = &e2apRicMsg->choice.initiatingMessage->value.choice.RICsubscriptionRequest;
411 ricSubscriptionReq->protocolIEs.list.count = elementCnt;
412 ricSubscriptionReq->protocolIEs.list.size = elementCnt * sizeof(RICsubscriptionRequest_IEs_t);
414 /* Initialize the subscription members */
415 RIC_ALLOC(ricSubscriptionReq->protocolIEs.list.array, \
416 ricSubscriptionReq->protocolIEs.list.size);
417 if(ricSubscriptionReq->protocolIEs.list.array == NULLP)
419 DU_LOG("\nE2AP : Memory allocation for RICSubscriptionRequestIEs failed");
420 RIC_FREE(e2apRicMsg->choice.initiatingMessage, sizeof(InitiatingMessageE2_t));
421 RIC_FREE(e2apRicMsg, (Size)sizeof(E2AP_PDU_t));
425 for(idx=0; idx<elementCnt; idx++)
427 RIC_ALLOC(ricSubscriptionReq->protocolIEs.list.array[idx],\
428 sizeof(RICsubscriptionRequest_IEs_t));
429 if(ricSubscriptionReq->protocolIEs.list.array[idx] == NULLP)
431 for(ieId=0; ieId<idx; ieId++)
433 RIC_FREE(ricSubscriptionReq->protocolIEs.list.array[ieId],\
434 sizeof(RICsubscriptionRequest_IEs_t));
436 RIC_FREE(ricSubscriptionReq->protocolIEs.list.array,\
437 ricSubscriptionReq->protocolIEs.list.size);
438 RIC_FREE(e2apRicMsg->choice.initiatingMessage, \
439 sizeof(InitiatingMessageE2_t));
440 RIC_FREE(e2apRicMsg, sizeof(E2AP_PDU_t));
445 /* Filling RIC Request Id */
447 ricSubscriptionReq->protocolIEs.list.array[idx]->id = ProtocolIE_IDE2_id_RICrequestID;
448 ricSubscriptionReq->protocolIEs.list.array[idx]->criticality = CriticalityE2_reject;
449 ricSubscriptionReq->protocolIEs.list.array[idx]->value.present =\
450 RICsubscriptionRequest_IEs__value_PR_RICrequestID;
452 BuildRicRequestId(&ricSubscriptionReq->protocolIEs.list.array[idx]->value.choice.RICrequestID);
455 /* Filling RAN Function Id */
457 ricSubscriptionReq->protocolIEs.list.array[idx]->id = ProtocolIE_IDE2_id_RANfunctionID;
458 ricSubscriptionReq->protocolIEs.list.array[idx]->criticality = CriticalityE2_reject;
459 ricSubscriptionReq->protocolIEs.list.array[idx]->value.present =\
460 RICsubscriptionRequest_IEs__value_PR_RANfunctionID;
461 ricSubscriptionReq->protocolIEs.list.array[idx]->value.choice.RANfunctionID = 1;
464 /* Filling RIC Subscription Details */
466 ricSubscriptionReq->protocolIEs.list.array[idx]->id = ProtocolIE_IDE2_id_RICsubscriptionDetails;
467 ricSubscriptionReq->protocolIEs.list.array[idx]->criticality = CriticalityE2_reject;
468 ricSubscriptionReq->protocolIEs.list.array[idx]->value.present =\
469 RICsubscriptionRequest_IEs__value_PR_RICsubscriptionDetails;
471 BuildRicSubsDetails(&(ricSubscriptionReq->protocolIEs.list.array[idx]->value.choice.RICsubscriptionDetails));
474 /* Prints the Msg formed */
475 xer_fprint(stdout, &asn_DEF_E2AP_PDU, e2apRicMsg);
477 cmMemset((U8 *)encBuf, 0, ENC_BUF_MAX_LEN);
479 encRetVal = aper_encode(&asn_DEF_E2AP_PDU, 0, e2apRicMsg, PrepFinalEncBuf,\
481 if(encRetVal.encoded == ENCODE_FAIL)
483 DU_LOG("\nE2AP : Could not encode RicSubscriptionRequest structure (at %s)\n",\
484 encRetVal.failed_type ? encRetVal.failed_type->name : "unknown");
489 DU_LOG("\nE2AP : Created APER encoded buffer for RicSubscriptionRequest\n");
490 for(int i=0; i< encBufSize; i++)
492 printf("%x",encBuf[i]);
498 if(SendE2APMsg(RIC_APP_MEM_REG, RIC_POOL) != ROK)
500 DU_LOG("\nE2AP : Sending RIC subscription Request failed");
508 /*******************************************************************
510 * @brief Handles received E2AP message and sends back response
514 * Function : E2APMsgHdlr
517 * - Decodes received E2AP control message
518 * - Prepares response message, encodes and sends to SCTP
521 * @return ROK - success
524 * ****************************************************************/
525 void E2APMsgHdlr(Buffer *mBuf)
532 asn_dec_rval_t rval; /* Decoder return value */
533 E2AP_PDU_t e2apasnmsg ;
535 DU_LOG("\nE2AP : Received E2AP message buffer");
538 /* Copy mBuf into char array to decode it */
539 SFndLenMsg(mBuf, &recvBufLen);
540 if(SGetSBuf(DFLT_REGION, DFLT_POOL, (Data **)&recvBuf, (Size)recvBufLen) != ROK)
542 DU_LOG("\nE2AP : Memory allocation failed");
545 if(SCpyMsgFix(mBuf, 0, recvBufLen, (Data *)recvBuf, ©Cnt) != ROK)
547 DU_LOG("\nE2AP : Failed while copying %d", copyCnt);
551 printf("\nE2AP : Received flat buffer to be decoded : ");
552 for(i=0; i< recvBufLen; i++)
554 printf("%x",recvBuf[i]);
557 /* Decoding flat buffer into E2AP messsage */
558 e2apMsg = &e2apasnmsg;
559 memset(e2apMsg, 0, sizeof(E2AP_PDU_t));
561 rval = aper_decode(0, &asn_DEF_E2AP_PDU, (void **)&e2apMsg, recvBuf, recvBufLen, 0, 0);
562 SPutSBuf(DFLT_REGION, DFLT_POOL, (Data *)recvBuf, (Size)recvBufLen);
563 if(rval.code == RC_FAIL || rval.code == RC_WMORE)
565 DU_LOG("\nE2AP : ASN decode failed");
569 xer_fprint(stdout, &asn_DEF_E2AP_PDU, e2apMsg);
571 switch(e2apMsg->present)
573 case E2AP_PDU_PR_initiatingMessage:
575 switch(e2apMsg->choice.initiatingMessage->value.present)
577 case InitiatingMessageE2__value_PR_E2setupRequest:
579 DU_LOG("\nE2AP : E2 setup request received");
580 BuildAndSendE2SetupRsp();
583 case InitiatingMessageE2__value_PR_RICindication:
585 DU_LOG("\nE2AP : RIC Indication Acknowledged");
590 DU_LOG("\nE2AP : Invalid type of intiating message [%d]",e2apMsg->choice.initiatingMessage->value.present);
593 }/* End of switch(initiatingMessage) */
596 case E2AP_PDU_PR_successfulOutcome:
598 switch(e2apMsg->choice.successfulOutcome->value.present)
600 case SuccessfulOutcomeE2__value_PR_RICsubscriptionResponse:
602 DU_LOG("\nE2AP : RICsubscriptionResponse Msg Acknowledged");
607 DU_LOG("\nE2AP : Invalid type of successfulOutcome message [%d]",e2apMsg->choice.successfulOutcome->value.present);
616 DU_LOG("\nE2AP : Invalid type message type ");
620 }/* End of switch(e2apMsg->present) */
623 BuildAndSendRicSubscriptionReq();
625 } /* End of E2APMsgHdlr */
628 /**********************************************************************
630 **********************************************************************/