+/*******************************************************************************
+################################################################################
+# Copyright (c) [2017-2019] [Radisys] #
+# #
+# Licensed under the Apache License, Version 2.0 (the "License"); #
+# you may not use this file except in compliance with the License. #
+# You may obtain a copy of the License at #
+# #
+# http://www.apache.org/licenses/LICENSE-2.0 #
+# #
+# Unless required by applicable law or agreed to in writing, software #
+# distributed under the License is distributed on an "AS IS" BASIS, #
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. #
+# See the License for the specific language governing permissions and #
+# limitations under the License. #
+################################################################################
+*******************************************************************************/
+
+/* This file contains F1AP message handler functions */
+#include "common_def.h"
+#include "cu_stub_sctp.h"
+#include "cu_stub_egtp.h"
+#include "OCTET_STRING.h"
+#include "cu_f1ap_msg_hdl.h"
+#include "cu_stub.h"
+
+/*******************************************************************
+ *
+ * @brief Build And send dummy Xn Setup request
+ *
+ * @details
+ *
+ * Function : BuildAndSendXnSetupReq
+ *
+ * Functionality:
+ * Build And send dummy Xn Setup request
+ *
+ * @params[in]
+ * @return void
+ *
+ ******************************************************************/
+void BuildAndSendXnSetupReq()
+{
+ uint8_t assocIdx = 0;
+ Buffer *mBuf = NULLP;
+ CuSctpAssocCb *assocCb = NULLP;
+
+ for(assocIdx = 0; assocIdx < sctpCb.numAssoc; assocIdx++)
+ {
+ assocCb = &sctpCb.assocCb[assocIdx];
+ if(assocCb->connUp && assocCb->intf == XN_INTERFACE && assocCb->destId == 0)
+ {
+ if(ODU_GET_MSG_BUF(1, 1, &mBuf) == ROK)
+ {
+ CMCHKPK(oduUnpackUInt8,(Data *)CU_ID, mBuf);
+ CMCHKPK(oduUnpackUInt8,XN_SETUP_REQ, mBuf);
+ ODU_PRINT_MSG(mBuf, 0,0);
+ if(sendOnSctpAssoc(assocCb, mBuf) != ROK)
+ {
+ DU_LOG("\nERROR --> CU_STUB: Failed to send XN setup request to peer CU");
+ }
+ }
+ break;
+ }
+ }
+}
+
+/*******************************************************************
+ *
+ * @brief Process received Xn Setup request
+ *
+ * @details
+ *
+ * Function : XNAPProcXnSetupReq
+ *
+ * Functionality:
+ * Fetch peer CU ID and store in assocCb
+ *
+ * @params[in] Pointer to destination Id
+ * Pointer to message buffer
+ * @return void
+ *
+ ******************************************************************/
+void XNAPProcXnSetupReq(uint32_t *destId, Buffer *mBuf)
+{
+ uint8_t cuId;
+
+ DU_LOG("\nINFO --> CU STUB : Received XN Setup Request");
+ CMCHKUNPK(oduPackUInt8, &(cuId), mBuf)
+ *destId = cuId;
+
+ BuildAndSendXnSetupRsp(*destId);
+}
+
+/*******************************************************************
+ *
+ * @brief Build And send dummy Xn Setup response
+ *
+ * @details
+ *
+ * Function : BuildAndSendXnSetupRsp
+ *
+ * Functionality:
+ * Build And send dummy Xn Setup response
+ *
+ * @params[in]
+ * @return void
+ *
+ ******************************************************************/
+void BuildAndSendXnSetupRsp(uint32_t destId)
+{
+ Buffer *mBuf = NULLP;
+
+ if(ODU_GET_MSG_BUF(1, 1, &mBuf) == ROK)
+ {
+ CMCHKPK(oduUnpackUInt8, CU_ID, mBuf);
+ CMCHKPK(oduUnpackUInt8, XN_SETUP_RSP, mBuf);
+ if(sctpSend(XN_INTERFACE, destId, mBuf))
+ {
+ DU_LOG("\nERROR --> CU_STUB: Failed to send XN setup response to peer CU");
+ }
+ }
+}
+
+/*******************************************************************
+ *
+ * @brief Process received Xn Setup response
+ *
+ * @details
+ *
+ * Function : XNAPProcXnSetupRsp
+ *
+ * Functionality:
+ * Fetch peer CU ID and store in assocCb
+ *
+ * @params[in] Pointer to destination Id
+ * Pointer to message buffer
+ * @return void
+ *
+ ******************************************************************/
+void XNAPProcXnSetupRsp(uint32_t *destId, Buffer *mBuf)
+{
+ uint8_t cuId;
+
+ DU_LOG("\nINFO --> CU STUB : Received XN Setup Response");
+ CMCHKUNPK(oduPackUInt8, &(cuId), mBuf)
+ *destId = cuId;
+}
+
+/*******************************************************************
+ *
+ * @brief Build And send dummy Handover request to Peer CU
+ *
+ * @details
+ *
+ * Function : BuildAndSendHOReq
+ *
+ * Functionality:
+ * Build And send dummy Handover request to Peer CU
+ *
+ * @params[in] Pointer to UE Cb
+ * Event type
+ * Message to be sent
+ * Message Length
+ * @return void
+ *
+ ******************************************************************/
+void BuildAndSendHOReq(CuUeCb *ueCb, XnEventType event, char *xnMsg, MsgLen xnMsgLen)
+{
+ Buffer *mBuf = NULLP;
+
+ if(ODU_GET_MSG_BUF(1, 1, &mBuf) == ROK)
+ {
+ if(ODU_ADD_POST_MSG_MULT((Data *)xnMsg, xnMsgLen, mBuf) == ROK)
+ {
+ CMCHKPK(oduUnpackUInt8, event, mBuf);
+ if(sctpSend(XN_INTERFACE, ueCb->hoInfo.targetId, mBuf) != ROK)
+ {
+ DU_LOG("\nERROR --> CU_STUB: Failed to send handover request to peer CU");
+ ueCb->state = UE_ACTIVE;
+ memset(&ueCb->hoInfo, 0, sizeof(HandoverInfo));
+ }
+ }
+ }
+}
+
+/*******************************************************************
+ *
+ * @brief Handle incoming messages at Xn interface
+ *
+ * @details
+ *
+ * Function : XNAPMsgHdlr
+ *
+ * Functionality:
+ * Fetch event type from message buffer and call appropriate
+ * handler
+ *
+ * @params[in] Pointer to destination Id
+ * Pointer to message buffer
+ * @return void
+ *
+ ******************************************************************/
+void XNAPMsgHdlr(uint32_t *destId, Buffer *mBuf)
+{
+ XnEventType event;
+
+ CMCHKUNPK(oduPackUInt8, &event, mBuf);
+
+ switch(event)
+ {
+ case XN_SETUP_REQ:
+ {
+ XNAPProcXnSetupReq(destId, mBuf);
+ break;
+ }
+
+ case XN_SETUP_RSP:
+ {
+ XNAPProcXnSetupRsp(destId, mBuf);
+ break;
+ }
+
+ case HO_REQ:
+ {
+ DU_LOG("\nINFO --> CU STUB : Received Handover Request at XNAP");
+
+//Handling of HO Request to be added in next gerrit
+#if 0
+ char *recvBuf;
+ MsgLen copyCnt;
+ MsgLen recvBufLen;
+ F1AP_PDU_t *f1apMsg = NULLP;
+ asn_dec_rval_t rval; /* Decoder return value */
+ F1AP_PDU_t f1apasnmsg ;
+
+ ODU_PRINT_MSG(mBuf, 0,0);
+
+ /* Copy mBuf into char array to decode it */
+ ODU_GET_MSG_LEN(mBuf, &recvBufLen);
+ CU_ALLOC(recvBuf, (Size)recvBufLen);
+
+ if(recvBuf == NULLP)
+ {
+ DU_LOG("\nERROR --> F1AP : Memory allocation failed");
+ return;
+ }
+ if(ODU_COPY_MSG_TO_FIX_BUF(mBuf, 0, recvBufLen, (Data *)recvBuf, ©Cnt) != ROK)
+ {
+ DU_LOG("\nERROR --> F1AP : Failed while copying %d", copyCnt);
+ return;
+ }
+
+ DU_LOG("\nDEBUG --> F1AP : Received flat buffer to be decoded : ");
+ for(i=0; i< recvBufLen; i++)
+ {
+ DU_LOG("%x",recvBuf[i]);
+ }
+
+ /* Decoding flat buffer into F1AP messsage */
+ f1apMsg = &f1apasnmsg;
+ memset(f1apMsg, 0, sizeof(F1AP_PDU_t));
+ rval = aper_decode(0, &asn_DEF_F1AP_PDU, (void **)&f1apMsg, recvBuf, recvBufLen, 0, 0);
+ CU_FREE(recvBuf, (Size)recvBufLen);
+
+ if(rval.code == RC_FAIL || rval.code == RC_WMORE)
+ {
+ DU_LOG("\nERROR --> F1AP : ASN decode failed");
+ return;
+ }
+ DU_LOG("\n");
+ xer_fprint(stdout, &asn_DEF_F1AP_PDU, f1apMsg);
+
+ procUeContextModificationResponse(0, f1apMsg, recvBuf, recvBufLen);
+#endif
+ break;
+ }
+ default:
+ DU_LOG("\nERROR --> CU_STUB : Invalid event [%d] received at XN interface", event);
+ break;
+ }
+}
+
+/**********************************************************************
+ End of file
+ **********************************************************************/