[Epic-ID: ODUHIGH-463][Task-ID: ODUHIGH-496] Dummy Xn Setup Request/Response
[o-du/l2.git] / src / cu_stub / cu_f1ap_msg_hdl.c
index c510a58..601637b 100644 (file)
@@ -177,7 +177,7 @@ S16 SendF1APMsg(Region region, Pool pool, uint32_t duId)
       {
          ODU_PRINT_MSG(mBuf, 0,0);
 
-         if(sctpSend(duId, mBuf) != ROK)
+         if(sctpSend(F1_INTERFACE, duId, mBuf) != ROK)
          {
             DU_LOG("\nERROR  -->  F1AP : SCTP Send failed");
             ODU_PUT_MSG_BUF(mBuf);
@@ -1519,6 +1519,28 @@ uint8_t  BuildDLRRCContainer(CuUeCb *ueCb, uint8_t rrcMsgType, RRCContainer_t *rr
          DU_LOG("\nERROR  -->  F1AP: Failed to fill DL-CCCH Msg at RRC SETUP");
    }
    else if(rrcMsgType == RRC_SETUP_COMPLETE)
+   {
+      DU_LOG("\nINFO --> F1AP : Sending NAS Authentication Request");
+      char authReqBuf[51] = {0x00, ueCb->pdcpSn++, 0x2a, 0x85, 0x4f, 0xc0, 0x0a, 0xc0, 0x40, 0x40, 0x00, 0x04, 0x2f, 0x58, 0x39, 0x12,\
+                             0x37, 0x15, 0x74, 0x16, 0x4c, 0x8d, 0xd3, 0x95, 0xa6, 0x9e, 0x94, 0x03, 0x24, 0x02, 0x00, 0x6f,\
+                             0x0b, 0x39, 0x5e, 0xbc, 0xb0, 0x00, 0x1a, 0xb1, 0xc1, 0x3f, 0x84, 0x4f, 0x77, 0xe3, 0x20, 0x00,\
+                             0x00, 0x00, 0x00};
+      bufLen = 51;
+      rrcContainer->size = bufLen;
+      CU_ALLOC(rrcContainer->buf, rrcContainer->size);
+      if(rrcContainer->buf != NULLP)
+      {
+         memset(rrcContainer->buf, 0, bufLen); 
+         memcpy(rrcContainer->buf, authReqBuf, bufLen);
+      }
+      else
+      {
+         DU_LOG("\nERROR  -->  F1AP : Memory allocation failure for RRC Container buffer");
+         ret = RFAILED;
+
+      }     
+   }
+   else if(rrcMsgType == NAS_AUTHENTICATION_RSP)
    {
       DU_LOG("\nINFO --> F1AP : Sending NAS Security mode command");
       char secModeBuf[30]={0x00, ueCb->pdcpSn++, 0x2e, 0x82, 0xaf, 0xc0, 0x7d, 0x1c, 0x4e, 0xfc, 0x80, 0x0f, 0xc0, 
@@ -1807,6 +1829,9 @@ uint8_t setDlRRCMsgType(CuUeCb *ueCb)
       case RRC_SETUP_COMPLETE:
          rrcMsgType = RRC_SETUP_COMPLETE;
          break;
+      case NAS_AUTHENTICATION_RSP:
+         rrcMsgType = NAS_AUTHENTICATION_RSP;
+         break;
       case NAS_SECURITY_MODE_COMPLETE:
          rrcMsgType = NAS_SECURITY_MODE_COMPLETE;
          break;
@@ -9291,7 +9316,7 @@ uint8_t BuildAndSendUeContextSetupReq(uint32_t duId, CuUeCb *ueCb)
       if(ueCb->state == UE_HANDOVER_IN_PROGRESS)
       {
          /* Spec 38.473 Sec 9.2.2.1 : For handover case, this IE shall be considered as target cell. */
-         SEARCH_DU_DB(duIdx, ueCb->hoInfo.targetDuId, targetDuDb);
+         SEARCH_DU_DB(duIdx, ueCb->hoInfo.targetId, targetDuDb);
          /* Since we are supporting only one cell per DU, accessing 0th index to
           * get target cell info */
          spCellId = targetDuDb->cellCb[0].nrCellId;
@@ -9629,7 +9654,7 @@ uint8_t procUeContextSetupResponse(uint32_t duId, F1AP_PDU_t *f1apMsg)
                    ueCb->gnbDuUeF1apId = duUeF1apId;
                    ueCb->gnbCuUeF1apId = cuUeF1apId;
                    ueCb->state = UE_HANDOVER_IN_PROGRESS;
-                   ueCb->hoInfo.targetDuId = duId; 
+                   ueCb->hoInfo.targetId = duId; 
                    (duDb->numUe)++;
 
                    ueCb->cellCb->ueCb[ueCb->cellCb->numUe] = ueCb;
@@ -9695,7 +9720,7 @@ uint8_t procUeContextSetupResponse(uint32_t duId, F1AP_PDU_t *f1apMsg)
 
                   /* Store source DU info in the new UE context created in
                    * tareget DU */
-                  ueCb->hoInfo.sourceDuId = srcDuDb->duId;
+                  ueCb->hoInfo.sourceId = srcDuDb->duId;
 
                   /* Copy the received container to UeCb */
                   memcpy(&ueCbInSrcDu->f1apMsgDb.duToCuContainer, duToCuRrcContainer, sizeof(OCTET_STRING_t));
@@ -9791,7 +9816,7 @@ uint8_t procUlRrcMsg(uint32_t duId, F1AP_PDU_t *f1apMsg)
                if(duDb->ueCb[duUeF1apId-1].state == UE_HANDOVER_IN_PROGRESS)
                {
                   uint8_t ueIdx = 0;
-                  uint8_t srcDuId = duDb->ueCb[duUeF1apId-1].hoInfo.sourceDuId;
+                  uint8_t srcDuId = duDb->ueCb[duUeF1apId-1].hoInfo.sourceId;
                   DuDb *srcDuDb = NULLP;
 
                   /* In target DU DB, mark UE as active and delete HO info */
@@ -9829,22 +9854,7 @@ uint8_t procUlRrcMsg(uint32_t duId, F1AP_PDU_t *f1apMsg)
       ueCb = &duDb->ueCb[duUeF1apId-1];
       ueCb->f1apMsgDb.dlRrcMsgCount++;
       rrcMsgType = setDlRRCMsgType(ueCb);
-      if(rrcMsgType == RRC_SETUP_COMPLETE)
-      {
-         DU_LOG("\nINFO  -->  F1AP: Sending DL RRC MSG for NAS Security Mode Command");
-         ret = BuildAndSendDLRRCMessageTransfer(duId, ueCb, srbId, rrcMsgType);
-      }
-      if(rrcMsgType == NAS_SECURITY_MODE_COMPLETE)
-      {
-         DU_LOG("\nINFO  -->  F1AP: Sending DL RRC MSG for RRC Security Mode Command"); 
-         ret = BuildAndSendDLRRCMessageTransfer(duId, ueCb, srbId, rrcMsgType);
-      }
-      else if(rrcMsgType == RRC_SECURITY_MODE_COMPLETE)
-      {
-         DU_LOG("\nINFO  -->  F1AP: Sending DL RRC MSG for RRC Registration Accept");
-         BuildAndSendDLRRCMessageTransfer(duId, ueCb, srbId, rrcMsgType);
-      }
-      else if(rrcMsgType == REGISTRATION_COMPLETE)
+      if(rrcMsgType == REGISTRATION_COMPLETE)
       {
          DU_LOG("\nINFO  -->  F1AP: Sending Ue Context Setup Request"); 
          ret = BuildAndSendUeContextSetupReq(duId, ueCb);
@@ -9854,6 +9864,11 @@ uint8_t procUlRrcMsg(uint32_t duId, F1AP_PDU_t *f1apMsg)
          DU_LOG("\nINFO  -->  F1AP: Sending UE Context Modification Request");
          BuildAndSendUeContextModificationReq(duId, ueCb, RRC_RECONFIG_COMPLETE_IND);
       }
+      else
+      {
+         /* In case rrcMsgType is RRC_SETUP_COMPLETE / NAS_AUTHENTICATION_RSP / NAS_SECURITY_MODE_COMPLETE / RRC_SECURITY_MODE_COMPLETE */
+         BuildAndSendDLRRCMessageTransfer(duId, ueCb, srbId, rrcMsgType);
+      }
    }
    return ret;
 }
@@ -10732,6 +10747,95 @@ uint8_t BuildDrbToBeModifiedList(uint32_t duId, CuUeCb *ueCb, DRBs_ToBeModified_
    return ret;
 }
 
+/*******************************************************************
+*
+* @brief Builds the DRB to be released Item IE
+*
+* @details
+*
+*    Function : FillDrbToBeRelItemList
+*
+*    Functionality: Constructs the DRB to be modified Mod Item Ies
+*
+* @params[in] struct DRBs_ToBeReleased_ItemIEs *drbItemIe
+*
+* @return ROK     - success
+*         RFAILED - failure
+*
+* ****************************************************************/
+
+uint8_t FillDrbToBeRelItemList(uint32_t duId, CuUeCb *ueCb, uint8_t arrIdx, struct DRBs_ToBeReleased_ItemIEs *drbItemIe)
+{
+   uint8_t drbIdx;
+
+   drbItemIe->id = ProtocolIE_ID_id_DRBs_ToBeReleased_Item;
+   drbItemIe->criticality = Criticality_reject;
+   drbItemIe->value.present = DRBs_ToBeReleased_ItemIEs__value_PR_DRBs_ToBeReleased_Item;
+   drbItemIe->value.choice.DRBs_ToBeReleased_Item.dRBID = DRB1 + arrIdx;
+
+   for(drbIdx = 0; drbIdx < ueCb->numDrb; drbIdx++)
+   {
+      if(ueCb->drbList[drbIdx].drbId == drbItemIe->value.choice.DRBs_ToBeReleased_Item.dRBID)
+      {
+         deleteEgtpTunnel(duId, ueCb->drbList[drbIdx].dlUpTnlInfo.teId);
+         CU_FREE(ueCb->drbList[drbIdx].snssai, sizeof(Snssai));
+         break;
+      }
+   }
+   return ROK;
+}
+
+/*******************************************************************
+*
+* @brief Builds the DRB to be released list 
+*
+* @details
+*
+*    Function : BuildDrbToBeReleasedList 
+*
+*    Functionality: Constructs the DRB to be released list
+*
+* @params[in] DRBs_ToBeReleased_List_t *drbSet 
+*
+* @return ROK     - success
+*         RFAILED - failure
+*
+* ****************************************************************/
+
+uint8_t BuildDrbToBeReleasedList(uint32_t duId, CuUeCb *ueCb, DRBs_ToBeReleased_List_t *drbSet)
+{
+   uint8_t ret = ROK;
+   uint8_t arrIdx =0;
+   uint8_t drbCnt =0;
+
+   drbCnt = MAX_DRB_MODIFIED_UE_MOD_REQ;
+   drbSet->list.count = drbCnt;
+   drbSet->list.size = drbCnt * sizeof(DRBs_ToBeReleased_ItemIEs_t *);
+   CU_ALLOC(drbSet->list.array, drbSet->list.size);
+   if(drbSet->list.array == NULLP)
+   {
+      DU_LOG("\nERROR  -->  F1AP : Memory allocation failed in BuildDrbToBeReleasedList");
+      return  RFAILED;
+   }
+   for(arrIdx=0; arrIdx<drbCnt; arrIdx++)
+   {
+      CU_ALLOC(drbSet->list.array[arrIdx], sizeof(DRBs_ToBeReleased_ItemIEs_t));
+      if(drbSet->list.array[arrIdx] == NULLP)
+      {
+         DU_LOG("\nERROR  -->  F1AP : Memory allocation failed in BuildDrbToBeReleasedList");
+         return  RFAILED;
+      }
+
+      ret = FillDrbToBeRelItemList(duId, ueCb, arrIdx, (DRBs_ToBeReleased_ItemIEs_t *)drbSet->list.array[arrIdx]);
+      if(ret != ROK)
+      {
+         DU_LOG("\nERROR  -->  F1AP : FillDrbToBeRelItemList failed");
+      }
+   }
+
+   return ret;
+}
+
 /*******************************************************************
 *
 * @brief freeing the DRB  item
@@ -10853,6 +10957,40 @@ void FreeDrbToBeModifiedList(DRBs_ToBeModified_List_t *drbSet)
 
 }
 
+/*******************************************************************
+*
+* @brief free the DRB to be modfified list
+*
+* @details
+*
+*    Function : FreeDrbToBeReleasedList
+*
+*    Functionality: free the DRB to be Release list
+*
+* @params[in] FreeDrbToBeReleasedList_t *drbSet
+*
+* @return ROK     - success
+*         RFAILED - failure
+*
+* ****************************************************************/
+void FreeDrbToBeReleasedList(DRBs_ToBeReleased_List_t *drbSet)
+{
+   uint8_t arrIdx =0;
+   struct DRBs_ToBeReleased_ItemIEs *drbItemIe;
+
+   if(drbSet->list.array)
+   {
+      for(arrIdx=0; arrIdx<drbSet->list.count ; arrIdx++)
+      {
+         if(drbSet->list.array[arrIdx] != NULLP)
+         {
+            CU_FREE(drbSet->list.array[arrIdx], sizeof(DRBs_ToBeReleased_ItemIEs_t));
+         }
+      }
+      CU_FREE(drbSet->list.array, drbSet->list.size);
+   }
+}
+
 /*******************************************************************
  *
  * @brief  free the UeContextModification Request 
@@ -10904,6 +11042,12 @@ void FreeUeContextModicationRequest(F1AP_PDU_t *f1apMsg)
                                  choice.DRBs_ToBeModified_List);
                            break;
                         }
+                     case ProtocolIE_ID_id_DRBs_ToBeReleased_List:
+                        {
+                           FreeDrbToBeReleasedList(&ueContextModifyReq->protocolIEs.list.array[arrIdx]->value.\
+                                 choice.DRBs_ToBeReleased_List);
+                           break;
+                        }
                     case ProtocolIE_ID_id_TransmissionActionIndicator:
                         break;
                     case ProtocolIE_ID_id_RRCContainer:
@@ -10976,7 +11120,7 @@ uint8_t BuildAndSendUeContextModificationReq(uint32_t duId, void *cuUeCb, UeCtxt
       ueContextModifyReq =&f1apMsg->choice.initiatingMessage->value.choice.UEContextModificationRequest;
 
       if(action == MODIFY_UE)
-         elementCnt = 4;
+         elementCnt = 5;
       else if(action == QUERY_CONFIG)
          elementCnt = 3;
       else if(action == RRC_RECONFIG_COMPLETE_IND)
@@ -11043,15 +11187,26 @@ uint8_t BuildAndSendUeContextModificationReq(uint32_t duId, void *cuUeCb, UeCtxt
          ret = BuildDrbToBeModifiedList(duId, ueCb, &(ueContextModifyReq->protocolIEs.list.array[ieIdx]->\
                   value.choice.DRBs_ToBeModified_List));
 
-         /* TODO: DRB to be release list */
-
          if(ret != ROK)
          {
             DU_LOG("\nERROR  -->  F1AP : BuildAndSendUeContextModificationReq(): Failed to build drb to be modified list");
             break;
          }
 
-         /* TODO: fill the RRC reconfiguration information in RRC Contaiiner ie in case of MODIFY_UE  */
+         /* DRB to be released list */
+         ieIdx++;
+         ueContextModifyReq->protocolIEs.list.array[ieIdx]->id = ProtocolIE_ID_id_DRBs_ToBeReleased_List;
+         ueContextModifyReq->protocolIEs.list.array[ieIdx]->criticality = Criticality_reject;
+         ueContextModifyReq->protocolIEs.list.array[ieIdx]->value.present =\
+                                                                 UEContextModificationRequestIEs__value_PR_DRBs_ToBeReleased_List;
+         ret = BuildDrbToBeReleasedList(duId, ueCb, &(ueContextModifyReq->protocolIEs.list.array[ieIdx]->\
+                  value.choice.DRBs_ToBeReleased_List));
+
+         if(ret != ROK)
+         {
+            DU_LOG("\nERROR  -->  F1AP : BuildAndSendUeContextModificationReq(): Failed to build drb to be deleted list");
+            break;
+         }
       }
       else if(action == QUERY_CONFIG)
       {
@@ -11743,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;
@@ -11767,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:
@@ -11776,6 +11936,11 @@ uint8_t procUeContextModificationResponse(uint32_t duId, F1AP_PDU_t *f1apMsg)
                 break; 
 
              }
+             case ProtocolIE_ID_id_DRBs_Modified_List:
+             {
+                DU_LOG("\nINFO  -->  Received DRBs Modified List");
+                break;
+             }
           case ProtocolIE_ID_id_SRBs_SetupMod_List:
              {
                 procSrbSetupModList(ueCb, &ueCtxtModRsp->protocolIEs.list.array[idx]->value.choice.SRBs_SetupMod_List);
@@ -11800,33 +11965,36 @@ uint8_t procUeContextModificationResponse(uint32_t duId, F1AP_PDU_t *f1apMsg)
     * UE context setup request to target DU */
    if(ueCb->state == UE_HANDOVER_IN_PROGRESS)
    {
-      uint8_t ueIdx = 0;
-      DuDb *tgtDuDb = NULLP;
-      CuUeCb *ueCbInTgtDu = NULLP;
-
-      SEARCH_DU_DB(duIdx, ueCb->hoInfo.targetDuId, 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.targetDuId, 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;
+               }
             }
          }
       }
@@ -11867,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++)
    {
@@ -12202,6 +12374,11 @@ uint8_t BuildAndSendPagingMsg(uint64_t gsTmsi, uint8_t duId)
       DU_LOG("\nERROR  -->  F1AP : BuildAndSendPagingMsg(): DuDb is empty");
       return ret; 
    }
+   if(duDb->numCells == 0)
+   {
+      DU_LOG("\nERROR  -->  F1AP : BuildAndSendPagingMsg(): No CELL is UP!");
+      return ret; 
+   }
 
    while(true)
    {
@@ -12511,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: