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"
34 /*******************************************************************
36 * @brief Sends E2 msg over SCTP
40 * Function : SendE2APMsg
42 * Functionality: Sends E2 msg over SCTP
44 * @params[in] Region region
46 * @return ROK - success
49 * ****************************************************************/
51 S16 SendE2APMsg(Region region, Pool pool)
55 if(ODU_GET_MSG_BUF(region, pool, &mBuf) == ROK)
57 if(ODU_ADD_POST_MSG_MULT((Data *)encBuf, encBufSize, mBuf) == ROK)
59 ODU_PRINT_MSG(mBuf, 0,0);
61 if(sctpSend(mBuf) != ROK)
63 DU_LOG("\nE2AP : SCTP Send for E2 failed");
64 ODU_PUT_MSG_BUF(mBuf);
70 DU_LOG("\nE2AP : ODU_ADD_POST_MSG_MULT failed");
71 ODU_PUT_MSG_BUF(mBuf);
74 ODU_PUT_MSG_BUF(mBuf);
78 DU_LOG("\nE2AP : Failed to allocate memory");
85 /*******************************************************************
87 * @brief Builds Global RIC Id Params
91 * Function : BuildGlobalRicId
93 * Functionality: Building the Plmn and ric id
95 * @params[in] GlobalRIC_ID_t *ricId
96 * @return ROK - success
99 * ****************************************************************/
101 S16 BuildGlobalRicId(GlobalRIC_ID_t *ricId)
104 uint8_t byteSize = 3;
108 ricId->pLMN_Identity.size = byteSize * sizeof(uint8_t);
109 RIC_ALLOC(ricId->pLMN_Identity.buf, ricId->pLMN_Identity.size);
110 buildPlmnId(ricCfgParams.plmn , ricId->pLMN_Identity.buf);
112 ricId->ric_ID.size = byteSize * sizeof(uint8_t);
113 RIC_ALLOC(ricId->ric_ID.buf, ricId->ric_ID.size);
114 fillBitString(&ricId->ric_ID, unused, byteSize, val);
119 /*******************************************************************
121 * @brief Builds and sends the E2SetupResponse
125 * Function : BuildAndSendE2SetupRsp
127 * Functionality: Constructs the F1SetupResponse message and sends
128 * it back to the DU through SCTP.
130 * @params[in] void **buf,Buffer to which encoded pattern is written into
131 * @params[in] int *size,size of buffer
133 * @return ROK - success
136 * ****************************************************************/
137 S16 BuildAndSendE2SetupRsp()
139 E2AP_PDU_t *e2apMsg = NULL;
140 E2setupResponse_t *e2SetupRsp;
141 asn_enc_rval_t encRetVal;
146 DU_LOG("\nE2AP : Building E2 Setup Response\n");
148 RIC_ALLOC(e2apMsg, sizeof(E2AP_PDU_t));
151 DU_LOG("\nE2AP : Memory allocation for E2AP-PDU failed");
154 e2apMsg->present = E2AP_PDU_PR_successfulOutcome;
155 RIC_ALLOC(e2apMsg->choice.successfulOutcome, sizeof(SuccessfulOutcomeE2_t));
156 if(e2apMsg->choice.successfulOutcome == NULLP)
158 DU_LOG("\nE2AP : Memory allocation for E2AP-PDU failed");
159 RIC_FREE(e2apMsg, sizeof(E2AP_PDU_t));
163 e2apMsg->choice.successfulOutcome->procedureCode = ProcedureCodeE2_id_E2setup;
164 e2apMsg->choice.successfulOutcome->criticality = CriticalityE2_reject;
165 e2apMsg->choice.successfulOutcome->value.present = \
166 SuccessfulOutcomeE2__value_PR_E2setupResponse;
167 e2SetupRsp = &e2apMsg->choice.successfulOutcome->value.choice.E2setupResponse;
170 e2SetupRsp->protocolIEs.list.count = elementCnt;
171 e2SetupRsp->protocolIEs.list.size = elementCnt * sizeof(E2setupResponseIEs_t);
173 RIC_ALLOC(e2SetupRsp->protocolIEs.list.array, \
174 e2SetupRsp->protocolIEs.list.size);
175 if(e2SetupRsp->protocolIEs.list.array == NULLP)
177 DU_LOG("\nE2AP : Memory allocation for E2ResponseIEs failed");
178 RIC_FREE(e2apMsg->choice.successfulOutcome, sizeof(SuccessfulOutcomeE2_t));
179 RIC_FREE(e2apMsg, sizeof(E2AP_PDU_t));
183 for(idx=0; idx<elementCnt; idx++)
185 RIC_ALLOC(e2SetupRsp->protocolIEs.list.array[idx], \
186 sizeof(E2setupResponseIEs_t));
187 if(e2SetupRsp->protocolIEs.list.array[idx] == NULLP)
189 RIC_FREE(e2SetupRsp->protocolIEs.list.array,\
190 e2SetupRsp->protocolIEs.list.size);
191 RIC_FREE(e2apMsg->choice.successfulOutcome, \
192 sizeof(SuccessfulOutcomeE2_t));
193 RIC_FREE(e2apMsg, sizeof(E2AP_PDU_t));
199 e2SetupRsp->protocolIEs.list.array[idx]->id = ProtocolIE_IDE2_id_GlobalRIC_ID;
200 e2SetupRsp->protocolIEs.list.array[idx]->criticality = CriticalityE2_reject;
201 e2SetupRsp->protocolIEs.list.array[idx]->value.present = \
202 E2setupResponseIEs__value_PR_GlobalRIC_ID;
204 BuildGlobalRicId(&(e2SetupRsp->protocolIEs.list.array[idx]->value.choice.GlobalRIC_ID));
206 xer_fprint(stdout, &asn_DEF_E2AP_PDU, e2apMsg);
207 memset(encBuf, 0, ENC_BUF_MAX_LEN);
209 encRetVal = aper_encode(&asn_DEF_E2AP_PDU, 0, e2apMsg, PrepFinalEncBuf, encBuf);
211 /* Check encode results */
212 if(encRetVal.encoded == ENCODE_FAIL)
214 DU_LOG("\nE2AP : Could not encode E2SetupResponse structure (at %s)\n",\
215 encRetVal.failed_type ? encRetVal.failed_type->name : "unknown");
220 DU_LOG("\nE2AP : Created APER encoded buffer for E2SetupResponse\n");
221 for(int i=0; i< encBufSize; i++)
223 printf("%x",encBuf[i]);
228 if(SendE2APMsg(RIC_APP_MEM_REG, RIC_POOL) != ROK)
230 DU_LOG("\nE2AP : Sending E2 Setup Response failed");
237 /*******************************************************************
239 * @brief Builds Ric Request Id
243 * Function : BuildRicRequestId
245 * Functionality: Building the Ric Request Id
247 * @params[in] RICrequestID_t *ricReqId
248 * @return ROK - success
251 * ****************************************************************/
253 S16 BuildRicRequestId(RICrequestID_t *ricReqId)
256 if(ricReqId != NULLP)
258 ricReqId->ricRequestorID = 1;
259 ricReqId->ricInstanceID = 1;
264 /*******************************************************************
266 * @brief Fills Ric Action To be Setup Item
270 * Function : fillSetupItems
272 * Functionality: Filling ricAction Id, RicActionType
274 * @params[in] RICaction_ToBeSetup_Item_t *setupItems
275 * @return pointer of type RICaction_ToBeSetup_Item_t
277 * ****************************************************************/
279 RICaction_ToBeSetup_Item_t* fillSetupItems(RICaction_ToBeSetup_Item_t *setupItems)
281 if(setupItems != NULLP)
283 setupItems->ricActionID = 0;
284 setupItems->ricActionType = RICactionType_report;
290 /*******************************************************************
292 * @brief Fills RIC Subscription Details Item List
296 * Function : fillSubsDetails
298 * Functionality: Fill the RIC Subscription Details Items List
300 * @params[in] RICaction_ToBeSetup_ItemIEs_t *items
301 * @return ROK - success
304 * ****************************************************************/
306 S16 fillSubsDetails(RICaction_ToBeSetup_ItemIEs_t *items)
310 items->id = ProtocolIE_IDE2_id_RICaction_ToBeSetup_Item;
311 items->criticality = CriticalityE2_ignore;
312 items->value.present = RICaction_ToBeSetup_ItemIEs__value_PR_RICaction_ToBeSetup_Item;
313 fillSetupItems(&(items->value.choice.RICaction_ToBeSetup_Item));
318 /*******************************************************************
320 * @brief builds RIC Subscription Details
324 * Function : BuildsRicSubsDetails
326 * Functionality: Builds the RIC Subscription Details
328 * @params[in] RICsubscriptionDetails_t *subsDetails
329 * @return ROK - success
332 * ****************************************************************/
334 S16 BuildRicSubsDetails(RICsubscriptionDetails_t *subsDetails)
339 if(subsDetails != NULLP)
341 /* Octet string to be build here */
342 /* Sending PLMN as Octect string */
343 uint8_t byteSize = 3;
344 subsDetails->ricEventTriggerDefinition.size = byteSize * sizeof(uint8_t);
345 RIC_ALLOC(subsDetails->ricEventTriggerDefinition.buf, subsDetails->ricEventTriggerDefinition.size);
346 buildPlmnId(ricCfgParams.plmn, subsDetails->ricEventTriggerDefinition.buf);
348 subsDetails->ricAction_ToBeSetup_List.list.count = elementCnt;
349 subsDetails->ricAction_ToBeSetup_List.list.size = \
350 elementCnt * sizeof(RICaction_ToBeSetup_ItemIEs_t);
351 RIC_ALLOC(subsDetails->ricAction_ToBeSetup_List.list.array, \
352 subsDetails->ricAction_ToBeSetup_List.list.size);
353 if(subsDetails->ricAction_ToBeSetup_List.list.array == NULLP)
355 DU_LOG("\nE2AP : Memory allocation for RICactionToBeSetup Items failed");
358 RIC_ALLOC(subsDetails->ricAction_ToBeSetup_List.list.array[0],\
359 sizeof(RICaction_ToBeSetup_ItemIEs_t));
360 fillSubsDetails(subsDetails->ricAction_ToBeSetup_List.list.array[0]);
365 /*******************************************************************
367 * @brief Builds and Send the RicSubscriptionReq
371 * Function : BuildAndSendRicSubscriptionReq
373 * Functionality:Fills the RicSubscriptionReq
375 * @return ROK - success
378 ******************************************************************/
380 S16 BuildAndSendRicSubscriptionReq()
383 E2AP_PDU_t *e2apRicMsg = NULL;
384 RICsubscriptionRequest_t *ricSubscriptionReq;
389 asn_enc_rval_t encRetVal; /* Encoder return value */
390 ricSubsStatus = TRUE;
392 DU_LOG("\nE2AP : Building RIC Subscription Request\n");
394 RIC_ALLOC(e2apRicMsg, sizeof(E2AP_PDU_t));
395 if(e2apRicMsg == NULLP)
397 DU_LOG("\nE2AP : Memory allocation for E2AP-PDU failed");
401 e2apRicMsg->present = E2AP_PDU_PR_initiatingMessage;
402 RIC_ALLOC(e2apRicMsg->choice.initiatingMessage, sizeof(InitiatingMessageE2_t));
403 if(e2apRicMsg->choice.initiatingMessage == NULLP)
405 DU_LOG("\nE2AP : Memory allocation for E2AP-PDU failed");
406 RIC_FREE(e2apRicMsg, sizeof(E2AP_PDU_t));
409 e2apRicMsg->choice.initiatingMessage->procedureCode = ProcedureCodeE2_id_RICsubscription;
410 e2apRicMsg->choice.initiatingMessage->criticality = CriticalityE2_reject;
411 e2apRicMsg->choice.initiatingMessage->value.present = InitiatingMessageE2__value_PR_RICsubscriptionRequest;
413 RIC_ALLOC(ricSubscriptionReq, sizeof(RICsubscriptionRequest_t));
414 ricSubscriptionReq = &e2apRicMsg->choice.initiatingMessage->value.choice.RICsubscriptionRequest;
417 ricSubscriptionReq->protocolIEs.list.count = elementCnt;
418 ricSubscriptionReq->protocolIEs.list.size = elementCnt * sizeof(RICsubscriptionRequest_IEs_t);
420 /* Initialize the subscription members */
421 RIC_ALLOC(ricSubscriptionReq->protocolIEs.list.array, \
422 ricSubscriptionReq->protocolIEs.list.size);
423 if(ricSubscriptionReq->protocolIEs.list.array == NULLP)
425 DU_LOG("\nE2AP : Memory allocation for RICSubscriptionRequestIEs failed");
426 RIC_FREE(e2apRicMsg->choice.initiatingMessage, sizeof(InitiatingMessageE2_t));
427 RIC_FREE(e2apRicMsg, (Size)sizeof(E2AP_PDU_t));
431 for(idx=0; idx<elementCnt; idx++)
433 RIC_ALLOC(ricSubscriptionReq->protocolIEs.list.array[idx],\
434 sizeof(RICsubscriptionRequest_IEs_t));
435 if(ricSubscriptionReq->protocolIEs.list.array[idx] == NULLP)
437 for(ieId=0; ieId<idx; ieId++)
439 RIC_FREE(ricSubscriptionReq->protocolIEs.list.array[ieId],\
440 sizeof(RICsubscriptionRequest_IEs_t));
442 RIC_FREE(ricSubscriptionReq->protocolIEs.list.array,\
443 ricSubscriptionReq->protocolIEs.list.size);
444 RIC_FREE(e2apRicMsg->choice.initiatingMessage, \
445 sizeof(InitiatingMessageE2_t));
446 RIC_FREE(e2apRicMsg, sizeof(E2AP_PDU_t));
451 /* Filling RIC Request Id */
453 ricSubscriptionReq->protocolIEs.list.array[idx]->id = ProtocolIE_IDE2_id_RICrequestID;
454 ricSubscriptionReq->protocolIEs.list.array[idx]->criticality = CriticalityE2_reject;
455 ricSubscriptionReq->protocolIEs.list.array[idx]->value.present =\
456 RICsubscriptionRequest_IEs__value_PR_RICrequestID;
458 BuildRicRequestId(&ricSubscriptionReq->protocolIEs.list.array[idx]->value.choice.RICrequestID);
461 /* Filling RAN Function Id */
463 ricSubscriptionReq->protocolIEs.list.array[idx]->id = ProtocolIE_IDE2_id_RANfunctionID;
464 ricSubscriptionReq->protocolIEs.list.array[idx]->criticality = CriticalityE2_reject;
465 ricSubscriptionReq->protocolIEs.list.array[idx]->value.present =\
466 RICsubscriptionRequest_IEs__value_PR_RANfunctionID;
467 ricSubscriptionReq->protocolIEs.list.array[idx]->value.choice.RANfunctionID = 1;
470 /* Filling RIC Subscription Details */
472 ricSubscriptionReq->protocolIEs.list.array[idx]->id = ProtocolIE_IDE2_id_RICsubscriptionDetails;
473 ricSubscriptionReq->protocolIEs.list.array[idx]->criticality = CriticalityE2_reject;
474 ricSubscriptionReq->protocolIEs.list.array[idx]->value.present =\
475 RICsubscriptionRequest_IEs__value_PR_RICsubscriptionDetails;
477 BuildRicSubsDetails(&(ricSubscriptionReq->protocolIEs.list.array[idx]->value.choice.RICsubscriptionDetails));
480 /* Prints the Msg formed */
481 xer_fprint(stdout, &asn_DEF_E2AP_PDU, e2apRicMsg);
483 memset(encBuf, 0, ENC_BUF_MAX_LEN);
485 encRetVal = aper_encode(&asn_DEF_E2AP_PDU, 0, e2apRicMsg, PrepFinalEncBuf,\
487 if(encRetVal.encoded == ENCODE_FAIL)
489 DU_LOG("\nE2AP : Could not encode RicSubscriptionRequest structure (at %s)\n",\
490 encRetVal.failed_type ? encRetVal.failed_type->name : "unknown");
495 DU_LOG("\nE2AP : Created APER encoded buffer for RicSubscriptionRequest\n");
496 for(int i=0; i< encBufSize; i++)
498 printf("%x",encBuf[i]);
504 if(SendE2APMsg(RIC_APP_MEM_REG, RIC_POOL) != ROK)
506 DU_LOG("\nE2AP : Sending RIC subscription Request failed");
514 /*******************************************************************
516 * @brief Handles received E2AP message and sends back response
520 * Function : E2APMsgHdlr
523 * - Decodes received E2AP control message
524 * - Prepares response message, encodes and sends to SCTP
527 * @return ROK - success
530 * ****************************************************************/
531 void E2APMsgHdlr(Buffer *mBuf)
538 asn_dec_rval_t rval; /* Decoder return value */
539 E2AP_PDU_t e2apasnmsg ;
541 DU_LOG("\nE2AP : Received E2AP message buffer");
542 ODU_PRINT_MSG(mBuf, 0,0);
544 /* Copy mBuf into char array to decode it */
545 ODU_GET_MSG_LEN(mBuf, &recvBufLen);
546 RIC_ALLOC(recvBuf, (Size)recvBufLen);
550 DU_LOG("\nE2AP : Memory allocation failed");
553 if(ODU_COPY_MSG_TO_FIX_BUF(mBuf, 0, recvBufLen, (Data *)recvBuf, ©Cnt) != ROK)
555 DU_LOG("\nE2AP : Failed while copying %d", copyCnt);
559 printf("\nE2AP : Received flat buffer to be decoded : ");
560 for(i=0; i< recvBufLen; i++)
562 printf("%x",recvBuf[i]);
565 /* Decoding flat buffer into E2AP messsage */
566 e2apMsg = &e2apasnmsg;
567 memset(e2apMsg, 0, sizeof(E2AP_PDU_t));
569 rval = aper_decode(0, &asn_DEF_E2AP_PDU, (void **)&e2apMsg, recvBuf, recvBufLen, 0, 0);
570 RIC_FREE(recvBuf, (Size)recvBufLen);
572 if(rval.code == RC_FAIL || rval.code == RC_WMORE)
574 DU_LOG("\nE2AP : ASN decode failed");
578 xer_fprint(stdout, &asn_DEF_E2AP_PDU, e2apMsg);
580 switch(e2apMsg->present)
582 case E2AP_PDU_PR_initiatingMessage:
584 switch(e2apMsg->choice.initiatingMessage->value.present)
586 case InitiatingMessageE2__value_PR_E2setupRequest:
588 DU_LOG("\nE2AP : E2 setup request received");
589 BuildAndSendE2SetupRsp();
592 case InitiatingMessageE2__value_PR_RICindication:
594 DU_LOG("\nE2AP : RIC Indication Acknowledged");
599 DU_LOG("\nE2AP : Invalid type of intiating message [%d]",e2apMsg->choice.initiatingMessage->value.present);
602 }/* End of switch(initiatingMessage) */
605 case E2AP_PDU_PR_successfulOutcome:
607 switch(e2apMsg->choice.successfulOutcome->value.present)
609 case SuccessfulOutcomeE2__value_PR_RICsubscriptionResponse:
611 DU_LOG("\nE2AP : RICsubscriptionResponse Msg Acknowledged");
616 DU_LOG("\nE2AP : Invalid type of successfulOutcome message [%d]",e2apMsg->choice.successfulOutcome->value.present);
625 DU_LOG("\nE2AP : Invalid type message type ");
629 }/* End of switch(e2apMsg->present) */
632 BuildAndSendRicSubscriptionReq();
634 } /* End of E2APMsgHdlr */
637 /**********************************************************************
639 **********************************************************************/