[Epic-ID: ODUHIGH-463][Task-ID: ODUHIGH-496] Dummy Xn Setup Request/Response 28/10628/2
authorlal.harshita <Harshita.Lal@radisys.com>
Wed, 1 Mar 2023 12:09:02 +0000 (17:39 +0530)
committerlal.harshita <Harshita.Lal@radisys.com>
Thu, 2 Mar 2023 09:13:30 +0000 (14:43 +0530)
Signed-off-by: lal.harshita <Harshita.Lal@radisys.com>
Change-Id: I147ea03ccfa38bc0ee1c326cae24c27638bb0005
Signed-off-by: lal.harshita <Harshita.Lal@radisys.com>
src/cu_stub/cu_f1ap_msg_hdl.c
src/cu_stub/cu_stub.h
src/cu_stub/cu_stub_sctp.c
src/cu_stub/cu_xnap_msg_hdl.c [new file with mode: 0644]

index 14f7a28..601637b 100644 (file)
@@ -11898,7 +11898,7 @@ uint8_t procServedCellPlmnList(ServedPLMNs_List_t *srvPlmn)
  *         RFAILED - failure
  *
  * ****************************************************************/
-uint8_t procUeContextModificationResponse(uint32_t duId, F1AP_PDU_t *f1apMsg)
+uint8_t procUeContextModificationResponse(uint32_t duId, F1AP_PDU_t *f1apMsg, char *recvBuf, MsgLen recvBufLen)
 {
    uint8_t idx=0, duIdx=0;
    uint8_t duUeF1apId = 0, cuUeF1apId = 0;
@@ -11922,6 +11922,11 @@ uint8_t procUeContextModificationResponse(uint32_t duId, F1AP_PDU_t *f1apMsg)
              {
                 duUeF1apId = ueCtxtModRsp->protocolIEs.list.array[idx]->value.choice.GNB_DU_UE_F1AP_ID;
                 ueCb = &duDb->ueCb[duUeF1apId-1];
+
+                if((ueCb->state == UE_HANDOVER_IN_PROGRESS) && (ueCb->hoInfo.HOType == Xn_Based_Inter_CU_HO))
+                {
+                   BuildAndSendHOReq(ueCb, HO_REQ, recvBuf, recvBufLen);
+                }
                 break;
              }
           case ProtocolIE_ID_id_DRBs_SetupMod_List:
@@ -11958,35 +11963,38 @@ uint8_t procUeContextModificationResponse(uint32_t duId, F1AP_PDU_t *f1apMsg)
 
    /* If UE is in handover and UE context is not yet created at target DU, then send
     * UE context setup request to target DU */
-   if(ueCb->state == UE_HANDOVER_IN_PROGRESS && ueCb->hoInfo.HOType == Inter_DU_HO)
+   if(ueCb->state == UE_HANDOVER_IN_PROGRESS)
    {
-      uint8_t ueIdx = 0;
-      DuDb *tgtDuDb = NULLP;
-      CuUeCb *ueCbInTgtDu = NULLP;
-
-      SEARCH_DU_DB(duIdx, ueCb->hoInfo.targetId, tgtDuDb);
-      if(tgtDuDb)
+      if(ueCb->hoInfo.HOType == Inter_DU_HO)
       {
-         /* Since DU UE F1AP ID assigned by target DU to this UE in handover is
-          * not known here, using CU UE F1AP ID to search for UE Cb in target DU
-          * DB */
-         for(ueIdx = 0; ueIdx < MAX_NUM_UE; ueIdx++)
+         uint8_t ueIdx = 0;
+         DuDb *tgtDuDb = NULLP;
+         CuUeCb *ueCbInTgtDu = NULLP;
+
+         SEARCH_DU_DB(duIdx, ueCb->hoInfo.targetId, tgtDuDb);
+         if(tgtDuDb)
          {
-            if(tgtDuDb->ueCb[ueIdx].gnbCuUeF1apId == cuUeF1apId)
+            /* Since DU UE F1AP ID assigned by target DU to this UE in handover is
+             * not known here, using CU UE F1AP ID to search for UE Cb in target DU
+             * DB */
+            for(ueIdx = 0; ueIdx < MAX_NUM_UE; ueIdx++)
             {
-               ueCbInTgtDu = &tgtDuDb->ueCb[ueIdx];
-               break;
+               if(tgtDuDb->ueCb[ueIdx].gnbCuUeF1apId == cuUeF1apId)
+               {
+                  ueCbInTgtDu = &tgtDuDb->ueCb[ueIdx];
+                  break;
+               }
             }
-         }
 
-         /* If UE context is not found in Target DU DU, send UE context setup
-          * request */
-         if(ueCbInTgtDu == NULLP)
-         {
-            if((BuildAndSendUeContextSetupReq(ueCb->hoInfo.targetId, ueCb)) != ROK)
+            /* If UE context is not found in Target DU DU, send UE context setup
+             * request */
+            if(ueCbInTgtDu == NULLP)
             {
-               DU_LOG("\nERROR  ->  F1AP : Failed at BuildAndSendUeContextSetupReq");
-               return RFAILED;
+               if((BuildAndSendUeContextSetupReq(ueCb->hoInfo.targetId, ueCb)) != ROK)
+               {
+                  DU_LOG("\nERROR  ->  F1AP : Failed at BuildAndSendUeContextSetupReq");
+                  return RFAILED;
+               }
             }
          }
       }
@@ -12027,6 +12035,10 @@ void procF1SetupReq(uint32_t *destDuId, F1AP_PDU_t *f1apMsg)
    GNB_DU_Served_Cells_Item_t *srvCellItem = NULLP; 
    GNB_DU_Served_Cells_List_t *duServedCell = NULLP;
 
+   /* Triggering XN setup request before F1 setup establishment */
+   if(LOCAL_NODE_TYPE == CLIENT)
+      BuildAndSendXnSetupReq();
+
    f1SetupReq = &f1apMsg->choice.initiatingMessage->value.choice.F1SetupRequest;
    for(ieIdx=0; ieIdx < f1SetupReq->protocolIEs.list.count; ieIdx++)
    {
@@ -12676,7 +12688,7 @@ void F1APMsgHdlr(uint32_t *duId, Buffer *mBuf)
                case SuccessfulOutcome__value_PR_UEContextModificationResponse:
                   {
                      DU_LOG("\nINFO  -->  F1AP : UE Context Modification Response received");
-                     procUeContextModificationResponse(*duId, f1apMsg);
+                     procUeContextModificationResponse(*duId, f1apMsg, recvBuf, recvBufLen);
                      break;
                   }
                case SuccessfulOutcome__value_PR_UEContextReleaseComplete:
index 180116f..08cb36b 100644 (file)
@@ -112,6 +112,13 @@ typedef enum
   Inter_DU_HO
 }HandoverType;
 
+typedef enum
+{
+   XN_SETUP_REQ,
+   XN_SETUP_RSP,
+   HO_REQ
+}XnEventType;
+
 typedef enum
 {
    CELL_INACTIVE,
index e9bd0d6..0a03f0d 100644 (file)
@@ -121,7 +121,6 @@ uint8_t sctpCfgReq()
    for(destIdx=0; destIdx < sctpCb.sctpCfg.xnSctpInfo.numDestNode; destIdx++)
    {
       sctpCb.assocCb[assocIdx].intf = XN_INTERFACE;
-      sctpCb.assocCb[assocIdx].destId = CU_ID + destIdx +1;
       sctpCb.assocCb[assocIdx].destPort = sctpCb.sctpCfg.xnSctpInfo.destCb[destIdx].destPort;
       sctpCb.assocCb[assocIdx].bReadFdSet = ROK;
       memset(&sctpCb.assocCb[assocIdx].sockFd, -1, sizeof(CmInetFd));
@@ -617,9 +616,9 @@ uint8_t processPolling(sctpSockPollParams *pollParams, CuSctpAssocCb *assocCb, u
          }
          else if(assocCb->connUp && assocCb->intf == XN_INTERFACE)
          {
-            //TODO : Handler for messages on XN interface to be added in future commits
             DU_LOG("\nDEBUG  -->  SCTP : Received message at XN interface");
             ODU_PRINT_MSG(pollParams->mBuf, 0,0);
+            XNAPMsgHdlr(&assocCb->destId, pollParams->mBuf);
             ODU_PUT_MSG_BUF(pollParams->mBuf);
          }
          else
@@ -631,6 +630,43 @@ uint8_t processPolling(sctpSockPollParams *pollParams, CuSctpAssocCb *assocCb, u
   return ROK;
 }/* End of sctpSockPoll() */
 
+/*******************************************************************
+ *
+ * @brief Send message on an SCTP Association
+ *
+ * @details
+ *
+ *    Function : sendOnSctpAssoc
+ *
+ *    Functionality:
+ *        Send message on SCTP association
+ *
+ * @params[in] 
+ * @return ROK     - success
+ *         RFAILED - failure
+ *
+ * ****************************************************************/
+uint8_t sendOnSctpAssoc(CuSctpAssocCb *assocCb, Buffer *mBuf)
+{
+   uint8_t          ret = ROK;
+   MsgLen           len = 0;          /* number of actually sent octets */
+   CmInetMemInfo    memInfo;
+   
+   memset(&memInfo , 0, sizeof(CmInetMemInfo));
+   memInfo.region = CU_APP_MEM_REG;    
+   memInfo.pool   = CU_POOL;
+
+   ret = cmInetSctpSendMsg(&assocCb->sockFd, &assocCb->destIpNetAddr, assocCb->destPort, &memInfo, mBuf, &len, 0, \
+      FALSE, 0, 0/*SCT_PROTID_NONE*/, RWOULDBLOCK);
+
+   if(ret != ROK && ret != RWOULDBLOCK)
+   {
+      DU_LOG("\nERROR  -->  SCTP : Send message failed");
+      return RFAILED;
+   }
+   return ROK;
+}
+
 /*******************************************************************
  *
  * @brief Send message on SCTP socket
@@ -649,27 +685,16 @@ uint8_t processPolling(sctpSockPollParams *pollParams, CuSctpAssocCb *assocCb, u
  * ****************************************************************/
 uint8_t sctpSend(InterfaceType intf, uint32_t destId, Buffer *mBuf)
 {
-   uint8_t          ret = ROK, assocIdx = 0;
-   MsgLen           len = 0;          /* number of actually sent octets */
-   CmInetMemInfo    memInfo;                        
-  
-   memset(&memInfo , 0, sizeof(CmInetMemInfo));
-   memInfo.region = CU_APP_MEM_REG;               
-   memInfo.pool   = CU_POOL;
+   uint8_t  assocIdx = 0;
 
    for(assocIdx=0; assocIdx < sctpCb.numAssoc; assocIdx++)
    {
       if((sctpCb.assocCb[assocIdx].intf == intf) && (sctpCb.assocCb[assocIdx].destId == destId))
       {
-         ret = cmInetSctpSendMsg(&sctpCb.assocCb[assocIdx].sockFd, &sctpCb.assocCb[assocIdx].destIpNetAddr, \
-                  sctpCb.assocCb[assocIdx].destPort, &memInfo, mBuf, &len, 0, FALSE, 0, 0/*SCT_PROTID_NONE*/, RWOULDBLOCK);
-
-         if(ret != ROK && ret != RWOULDBLOCK)
-         {
-            DU_LOG("\nERROR  -->  SCTP : Send message failed");
-            return RFAILED;
-         }
-         return ROK;
+         if(sendOnSctpAssoc(&sctpCb.assocCb[assocIdx], mBuf) == ROK)
+            return ROK;
+         else
+            break;
       }
    }
    DU_LOG("\nERROR  -->  SCTP : Dest ID [%d] at Interface [%d] not found in SCTP DestCb list. Failed to send message", destId, intf);
diff --git a/src/cu_stub/cu_xnap_msg_hdl.c b/src/cu_stub/cu_xnap_msg_hdl.c
new file mode 100644 (file)
index 0000000..26d7329
--- /dev/null
@@ -0,0 +1,286 @@
+/*******************************************************************************
+################################################################################
+#   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, &copyCnt) != 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
+ **********************************************************************/