#include "ProtocolIE-Field.h"
#include "ProtocolExtensionField.h"
#include "ProtocolIE-SingleContainer.h"
+#include "F1SetupResponse.h"
+#include "SuccessfulOutcome.h"
+#include "InitiatingMessage.h"
+#include "NonDynamic5QIDescriptor.h"
+#include "AveragingWindow.h"
+#include "MaxDataBurstVolume.h"
+#include "Flows-Mapped-To-DRB-Item.h"
+#include "SliceSupportItem.h"
+#include "ServedPLMNs-Item.h"
#include "F1AP-PDU.h"
+#include "ULUPTNLInformation-ToBeSetup-Item.h"
+#include "ULConfiguration.h"
#include "ModulationOrder.h"
#include "BandNR.h"
#include "UE-CapabilityRAT-Container.h"
#include "CNUEPagingIdentity.h"
#include "PagingCell-Item.h"
#include "UL-DCCH-Message.h"
+#include "DRX-ConfigRrc.h"
#include "cu_stub_sctp.h"
#include "cu_stub_egtp.h"
#include "cu_f1ap_msg_hdl.h"
#include "cu_stub.h"
+CuGlobalCb cuCb;
+char encBuf[ENC_BUF_MAX_LEN];
uint8_t fillCellGrpCfg(CuUeCb *ueCb, OCTET_STRING_t *cellGrp, bool updateAllRbCfg);
uint8_t fillRrcReconfig(CuUeCb *ueCb, RRCReconfiguration_t *rrcReconfig, bool updateAllRbCfg);
{
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);
uint8_t idx,ieIdx;
uint8_t elementCnt,cellCnt;
F1AP_PDU_t *f1apMsg = NULL;
- F1SetupResponse_t *f1SetupRsp;
- GNB_CU_Name_t *cuName;
+ F1SetupResponse_t *f1SetupRsp = NULL;
+ GNB_CU_Name_t *cuName = NULL;
Cells_to_be_Activated_List_t *cellToActivate;
- RRC_Version_t *rrcVer;
+ RRC_Version_t *rrcVer = NULL;
asn_enc_rval_t encRetVal;
DU_LOG("\nINFO --> F1AP : Building F1 Setup Response\n");
SuccessfulOutcome__value_PR_F1SetupResponse;
f1SetupRsp = &f1apMsg->choice.successfulOutcome->value.choice.F1SetupResponse;
- elementCnt = 4;
+ elementCnt = 3;
f1SetupRsp->protocolIEs.list.count = elementCnt;
f1SetupRsp->protocolIEs.list.size = elementCnt*sizeof(F1SetupResponseIEs_t *);
F1SetupResponseIEs__value_PR_TransactionID;
f1SetupRsp->protocolIEs.list.array[idx]->value.choice.TransactionID =\
TRANS_ID;
-
+#if 0
+ /* CU name IE is of type printableString_t which wireshark is unable to decode.
+ * However this string is decoded successfully on online decoders.
+ * Since this is an optional IE and the value received in it are not
+ * used as of now, eliminating this IE for now to avoid wireshark error.
+ */
/*CU Name*/
idx++;
f1SetupRsp->protocolIEs.list.array[idx]->id = ProtocolIE_ID_id_gNB_CU_Name;
f1SetupRsp->protocolIEs.list.array[idx]->criticality = Criticality_ignore;
- f1SetupRsp->protocolIEs.list.array[idx]->value.present = \
- F1SetupResponseIEs__value_PR_GNB_CU_Name;
+ f1SetupRsp->protocolIEs.list.array[idx]->value.present = F1SetupResponseIEs__value_PR_GNB_CU_Name;
cuName = &f1SetupRsp->protocolIEs.list.array[idx]->value.choice.GNB_CU_Name;
- cuName->size = sizeof(cuCb.cuCfgParams.cuName);
+ cuName->size = strlen((char *)cuCb.cuCfgParams.cuName);
- CU_ALLOC(cuName->buf, sizeof(cuName->size));
+ CU_ALLOC(cuName->buf, cuName->size);
if(cuName->buf == NULLP)
{
for(ieIdx=0; ieIdx<elementCnt; ieIdx++)
{
- CU_FREE(f1SetupRsp->protocolIEs.list.array[ieIdx],\
- sizeof(F1SetupResponseIEs_t));
+ CU_FREE(f1SetupRsp->protocolIEs.list.array[ieIdx], sizeof(F1SetupResponseIEs_t));
}
- CU_FREE(f1SetupRsp->protocolIEs.list.array,\
- elementCnt * sizeof(F1SetupResponseIEs_t *));
- CU_FREE(f1apMsg->choice.successfulOutcome,\
- sizeof(SuccessfulOutcome_t));
+ CU_FREE(f1SetupRsp->protocolIEs.list.array, elementCnt * sizeof(F1SetupResponseIEs_t *));
+ CU_FREE(f1apMsg->choice.successfulOutcome, sizeof(SuccessfulOutcome_t));
CU_FREE(f1apMsg, sizeof(F1AP_PDU_t));
return RFAILED;
}
strcpy((char*)cuName->buf, (char*)cuCb.cuCfgParams.cuName);
+#endif
/*Cells to be activated list*/
idx++;
- f1SetupRsp->protocolIEs.list.array[idx]->id = \
- ProtocolIE_ID_id_Cells_to_be_Activated_List ;
+ f1SetupRsp->protocolIEs.list.array[idx]->id = ProtocolIE_ID_id_Cells_to_be_Activated_List ;
f1SetupRsp->protocolIEs.list.array[idx]->criticality = Criticality_reject;
- f1SetupRsp->protocolIEs.list.array[idx]->value.present = \
- F1SetupResponseIEs__value_PR_Cells_to_be_Activated_List;
- cellToActivate = &f1SetupRsp->protocolIEs.list.array[idx]->value.choice.\
- Cells_to_be_Activated_List;
+ f1SetupRsp->protocolIEs.list.array[idx]->value.present = F1SetupResponseIEs__value_PR_Cells_to_be_Activated_List;
+ cellToActivate = &f1SetupRsp->protocolIEs.list.array[idx]->value.choice.Cells_to_be_Activated_List;
+
cellCnt=1;
cellToActivate->list.count = cellCnt;
- cellToActivate->list.size = \
- cellCnt*sizeof(struct Cells_to_be_Activated_List_ItemIEs *);
- CU_ALLOC(cellToActivate->list.array,\
- sizeof(struct Cells_to_be_Activated_List_ItemIEs *));
+ cellToActivate->list.size = cellCnt * sizeof(struct Cells_to_be_Activated_List_ItemIEs *);
+ CU_ALLOC(cellToActivate->list.array, sizeof(struct Cells_to_be_Activated_List_ItemIEs *));
if(cellToActivate->list.array == NULLP)
{
CU_FREE(cuName->buf, sizeof(cuName->size));
for(ieIdx=0; ieIdx<elementCnt; ieIdx++)
{
- CU_FREE(f1SetupRsp->protocolIEs.list.array[ieIdx],\
- sizeof(F1SetupResponseIEs_t));
+ CU_FREE(f1SetupRsp->protocolIEs.list.array[ieIdx], sizeof(F1SetupResponseIEs_t));
}
- CU_FREE(f1SetupRsp->protocolIEs.list.array,\
- elementCnt * sizeof(F1SetupResponseIEs_t *));
+ CU_FREE(f1SetupRsp->protocolIEs.list.array, elementCnt * sizeof(F1SetupResponseIEs_t *));
CU_FREE(f1apMsg->choice.successfulOutcome, sizeof(SuccessfulOutcome_t));
CU_FREE(f1apMsg, sizeof(F1AP_PDU_t));
return RFAILED;
CU_ALLOC(cellToActivate->list.array[ieIdx],sizeof(struct Cells_to_be_Activated_List_ItemIEs ));
if(cellToActivate->list.array[ieIdx] == NULLP)
{
- CU_FREE(cellToActivate->list.array,\
- sizeof(struct Cells_to_be_Activated_List_ItemIEs *));
+ CU_FREE(cellToActivate->list.array, sizeof(struct Cells_to_be_Activated_List_ItemIEs *));
CU_FREE(cuName->buf, sizeof(cuName->size));
for(ieIdx=0; ieIdx<elementCnt; ieIdx++)
{
- CU_FREE(f1SetupRsp->protocolIEs.list.array[ieIdx], \
- sizeof(F1SetupResponseIEs_t));
+ CU_FREE(f1SetupRsp->protocolIEs.list.array[ieIdx], sizeof(F1SetupResponseIEs_t));
}
- CU_FREE(f1SetupRsp->protocolIEs.list.array, \
- elementCnt * sizeof(F1SetupResponseIEs_t *));
- CU_FREE(f1apMsg->choice.successfulOutcome, \
- sizeof(SuccessfulOutcome_t));
+ CU_FREE(f1SetupRsp->protocolIEs.list.array, elementCnt * sizeof(F1SetupResponseIEs_t *));
+ CU_FREE(f1apMsg->choice.successfulOutcome, sizeof(SuccessfulOutcome_t));
CU_FREE(f1apMsg, sizeof(F1AP_PDU_t));
return RFAILED;
}
return RFAILED;
}
memcpy(&cellToActivate->list.array[0]->value.choice.Cells_to_be_Activated_List_Item.nRCGI.nRCellIdentity, nrcellId, sizeof(BIT_STRING_t));
+
/* RRC Version */
idx++;
f1SetupRsp->protocolIEs.list.array[idx]->id = \
encRetVal = aper_encode(&asn_DEF_F1AP_PDU, 0, f1apMsg, PrepFinalEncBuf, encBuf);
/* Clean up */
- CU_FREE(rrcVer->latest_RRC_Version.buf, sizeof(uint8_t));
- CU_FREE(cuName->buf, sizeof(cuName->size));
+ if(rrcVer)
+ CU_FREE(rrcVer->latest_RRC_Version.buf, sizeof(uint8_t));
+ if(cuName)
+ CU_FREE(cuName->buf, cuName->size);
for(idx=0; idx<elementCnt; idx++)
{
CU_FREE(f1SetupRsp->protocolIEs.list.array[idx], sizeof(F1SetupResponseIEs_t));
xer_fprint(stdout, &asn_DEF_DL_CCCH_MessageType, &dl_CCCH_Msg);
memset(encBuf, 0, ENC_BUF_MAX_LEN);
encBufSize = 0;
- encRetVal = aper_encode(&asn_DEF_DL_CCCH_MessageType, 0, &dl_CCCH_Msg, PrepFinalEncBuf, encBuf);
+ encRetVal = uper_encode(&asn_DEF_DL_CCCH_MessageType, 0, &dl_CCCH_Msg, PrepFinalEncBuf, encBuf);
/* Encode results */
if(encRetVal.encoded == ENCODE_FAIL)
{
*
* ****************************************************************/
-uint8_t fillDlDcchRrcMsg(CuUeCb *ueCb, RRCContainer_t *rrcContainer)
+uint8_t fillDlDcchRrcMsg(CuUeCb *ueCb, RRCContainer_t *rrcContainer, bool updateAllRbCfg)
{
uint8_t ret = ROK;
uint16_t idx2 = 0, drbIdx = 0, srbIdx = 0;
if(dl_DCCH_Msg.message.choice.c1->choice.rrcReconfiguration != NULLP)
{
DU_LOG("\nDEBUG --> F1AP : Filling DL DCCH RRC Reconfiguration Message ");
- fillRrcReconfig(ueCb, dl_DCCH_Msg.message.choice.c1->choice.rrcReconfiguration, false);
+ fillRrcReconfig(ueCb, dl_DCCH_Msg.message.choice.c1->choice.rrcReconfiguration, updateAllRbCfg);
if(ret == ROK)
{
/* If RB configuration are filled successfully in RRC Reconfiguration, mark these
xer_fprint(stdout, &asn_DEF_DL_DCCH_MessageType, &dl_DCCH_Msg);
memset(encBuf, 0, ENC_BUF_MAX_LEN);
encBufSize = 0;
- encRetVal = aper_encode(&asn_DEF_DL_DCCH_MessageType, 0, &dl_DCCH_Msg, PrepFinalEncBuf, encBuf);
+ encRetVal = uper_encode(&asn_DEF_DL_DCCH_MessageType, 0, &dl_DCCH_Msg, PrepFinalEncBuf, encBuf);
/* Encode results */
if(encRetVal.encoded == ENCODE_FAIL)
{
}
else if(rrcMsgType == RRC_SETUP_COMPLETE)
{
- DU_LOG("\nINFO --> F1AP : Sending Security mode command");
- char secModeBuf[9]={0x00, 0x02, 0x22, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00};
+ 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,
+ 0x0b, 0xa0, 0x20, 0x40, 0x9e, 0x0e, 0x1e, 0x0e, 0x1c, 0x26, 0xc0, 0x20, 0x40, 0x00, 0x00, 0x00, 0x00};
+ bufLen =30;
+ rrcContainer->size = bufLen;
+ CU_ALLOC(rrcContainer->buf, rrcContainer->size);
+ if(rrcContainer->buf != NULLP)
+ {
+ memset(rrcContainer->buf, 0, bufLen);
+ memcpy(rrcContainer->buf, secModeBuf, bufLen);
+ }
+ else
+ {
+ DU_LOG("\nERROR --> F1AP : Memory allocation failure for RRC Container buffer");
+ ret = RFAILED;
+ }
+ }
+ else if(rrcMsgType == NAS_SECURITY_MODE_COMPLETE)
+ {
+ DU_LOG("\nINFO --> F1AP : Sending RRC Security mode command");
+ char secModeBuf[9]={0x00, ueCb->pdcpSn++, 0x22, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00};
bufLen =9;
rrcContainer->size = bufLen;
CU_ALLOC(rrcContainer->buf, rrcContainer->size);
ret = RFAILED;
}
}
- else if(rrcMsgType == SECURITY_MODE_COMPLETE)
+ else if(rrcMsgType == RRC_SECURITY_MODE_COMPLETE)
{
/*Hardcoded RRC Container from reference logs*/
DU_LOG("\nINFO --> F1AP : Sending Registration accept");
- char buf[14] ={0x00, 0x03, 0x2a, 0x80, 0xaf, 0xc0, 0x08, 0x40, 0x20, 0x20, 0x00, 0x00, 0x00, 0x00};
+ char buf[14] ={0x00, ueCb->pdcpSn++, 0x2a, 0x80, 0xaf, 0xc0, 0x08, 0x40, 0x20, 0x20, 0x00, 0x00, 0x00, 0x00};
bufLen =14;
rrcContainer->size = bufLen;
CU_ALLOC(rrcContainer->buf, rrcContainer->size);
}
else if(rrcMsgType == UE_CONTEXT_SETUP_RSP)
{
+ uint16_t tmpBufIdx = 0, bufIdx = 0;
+ RRCContainer_t rrcContainerTmp;
DU_LOG("\nINFO --> F1AP : Filling DL DCCH RRC Message for RRC Reconfiguration ");
- ret = fillDlDcchRrcMsg(ueCb, rrcContainer);
+ ret = fillDlDcchRrcMsg(ueCb, &rrcContainerTmp, false);
+ rrcContainer->size = rrcContainerTmp.size + 2;
+ CU_ALLOC(rrcContainer->buf, rrcContainer->size);
+ if(rrcContainer->buf != NULLP)
+ {
+ memset(rrcContainer->buf, 0, rrcContainer->size);
+ rrcContainer->buf[0] = 0x00;
+ rrcContainer->buf[1] = ueCb->pdcpSn++; //PDCP SN
+ for(bufIdx = 2, tmpBufIdx = 0; bufIdx < rrcContainer->size; bufIdx++, tmpBufIdx++)
+ {
+ rrcContainer->buf[bufIdx] = rrcContainerTmp.buf[tmpBufIdx];
+ }
+ }
if(ret == RFAILED)
DU_LOG("\nERROR --> F1AP: Failed to fill DL-DCCH Msg for RRC Reconfiguration");
}
case RRC_SETUP_COMPLETE:
rrcMsgType = RRC_SETUP_COMPLETE;
break;
- case SECURITY_MODE_COMPLETE:
- rrcMsgType = SECURITY_MODE_COMPLETE;
+ case NAS_AUTHENTICATION_RSP:
+ rrcMsgType = NAS_AUTHENTICATION_RSP;
+ break;
+ case NAS_SECURITY_MODE_COMPLETE:
+ rrcMsgType = NAS_SECURITY_MODE_COMPLETE;
+ break;
+ case RRC_SECURITY_MODE_COMPLETE:
+ rrcMsgType = RRC_SECURITY_MODE_COMPLETE;
break;
case REGISTRATION_COMPLETE:
rrcMsgType = REGISTRATION_COMPLETE;
return rrcMsgType;
}
+#ifdef NR_DRX
+/*******************************************************************
+ *
+ * @brief fill long cycle offset value of drx
+ *
+ * @details
+ *
+ * Function : fillLongCycleOffsetValue
+ *
+ * Functionality: fill long cycle offset value of drx
+ *
+ * @params[in] DrxLongCycleStartOffset drxLongCycleStartOffset,
+ * struct DRX_ConfigRrc__drx_LongCycleStartOffset recvedLongCycleOffsetVal
+ *
+ * @return ROK - success
+ * RFAILED - failure
+ *
+ * ****************************************************************/
+void fillLongCycleOffsetValue(DrxLongCycleStartOffset *drxLongCycleStartOffset, struct DRX_ConfigRrc__drx_LongCycleStartOffset *recvedLongCycleOffsetVal)
+{
+
+ drxLongCycleStartOffset->drxLongCycleStartOffsetChoice = recvedLongCycleOffsetVal->present;
+ switch(recvedLongCycleOffsetVal->present)
+ {
+ case DRX_ConfigRrc__drx_LongCycleStartOffset_PR_ms10:
+ {
+ drxLongCycleStartOffset->drxLongCycleStartOffsetVal = recvedLongCycleOffsetVal->choice.ms10;
+ break;
+ }
+ case DRX_ConfigRrc__drx_LongCycleStartOffset_PR_ms20:
+ {
+ drxLongCycleStartOffset->drxLongCycleStartOffsetVal = recvedLongCycleOffsetVal->choice.ms20;
+ break;
+ }
+ case DRX_ConfigRrc__drx_LongCycleStartOffset_PR_ms32:
+ {
+ drxLongCycleStartOffset->drxLongCycleStartOffsetVal = recvedLongCycleOffsetVal->choice.ms32;
+ break;
+ }
+ case DRX_ConfigRrc__drx_LongCycleStartOffset_PR_ms40:
+ {
+ drxLongCycleStartOffset->drxLongCycleStartOffsetVal = recvedLongCycleOffsetVal->choice.ms40;
+ break;
+ }
+ case DRX_ConfigRrc__drx_LongCycleStartOffset_PR_ms60:
+ {
+ drxLongCycleStartOffset->drxLongCycleStartOffsetVal = recvedLongCycleOffsetVal->choice.ms60;
+ break;
+ }
+ case DRX_ConfigRrc__drx_LongCycleStartOffset_PR_ms64:
+ {
+ drxLongCycleStartOffset->drxLongCycleStartOffsetVal = recvedLongCycleOffsetVal->choice.ms64;
+ break;
+ }
+ case DRX_ConfigRrc__drx_LongCycleStartOffset_PR_ms70:
+ {
+ drxLongCycleStartOffset->drxLongCycleStartOffsetVal = recvedLongCycleOffsetVal->choice.ms70;
+ break;
+ }
+ case DRX_ConfigRrc__drx_LongCycleStartOffset_PR_ms80:
+ {
+ drxLongCycleStartOffset->drxLongCycleStartOffsetVal = recvedLongCycleOffsetVal->choice.ms80;
+ break;
+ }
+ case DRX_ConfigRrc__drx_LongCycleStartOffset_PR_ms128:
+ {
+ drxLongCycleStartOffset->drxLongCycleStartOffsetVal = recvedLongCycleOffsetVal->choice.ms128;
+ break;
+ }
+ case DRX_ConfigRrc__drx_LongCycleStartOffset_PR_ms160:
+ {
+ drxLongCycleStartOffset->drxLongCycleStartOffsetVal = recvedLongCycleOffsetVal->choice.ms160;
+ break;
+ }
+ case DRX_ConfigRrc__drx_LongCycleStartOffset_PR_ms256:
+ {
+ drxLongCycleStartOffset->drxLongCycleStartOffsetVal = recvedLongCycleOffsetVal->choice.ms256;
+ break;
+ }
+ case DRX_ConfigRrc__drx_LongCycleStartOffset_PR_ms320:
+ {
+ drxLongCycleStartOffset->drxLongCycleStartOffsetVal = recvedLongCycleOffsetVal->choice.ms320;
+ break;
+ }
+ case DRX_ConfigRrc__drx_LongCycleStartOffset_PR_ms512:
+ {
+ drxLongCycleStartOffset->drxLongCycleStartOffsetVal = recvedLongCycleOffsetVal->choice.ms512;
+ break;
+ }
+ case DRX_ConfigRrc__drx_LongCycleStartOffset_PR_ms640:
+ {
+ drxLongCycleStartOffset->drxLongCycleStartOffsetVal = recvedLongCycleOffsetVal->choice.ms640;
+ break;
+ }
+ case DRX_ConfigRrc__drx_LongCycleStartOffset_PR_ms1024:
+ {
+ drxLongCycleStartOffset->drxLongCycleStartOffsetVal = recvedLongCycleOffsetVal->choice.ms1024;
+ break;
+ }
+ case DRX_ConfigRrc__drx_LongCycleStartOffset_PR_ms1280:
+ {
+ drxLongCycleStartOffset->drxLongCycleStartOffsetVal = recvedLongCycleOffsetVal->choice.ms1280;
+ break;
+ }
+ case DRX_ConfigRrc__drx_LongCycleStartOffset_PR_ms2048:
+ {
+ drxLongCycleStartOffset->drxLongCycleStartOffsetVal = recvedLongCycleOffsetVal->choice.ms2048;
+ break;
+ }
+ case DRX_ConfigRrc__drx_LongCycleStartOffset_PR_ms2560:
+ {
+ drxLongCycleStartOffset->drxLongCycleStartOffsetVal = recvedLongCycleOffsetVal->choice.ms2560;
+ break;
+ }
+ case DRX_ConfigRrc__drx_LongCycleStartOffset_PR_ms5120:
+ {
+ drxLongCycleStartOffset->drxLongCycleStartOffsetVal = recvedLongCycleOffsetVal->choice.ms5120;
+ break;
+ }
+ case DRX_ConfigRrc__drx_LongCycleStartOffset_PR_ms10240:
+ {
+ drxLongCycleStartOffset->drxLongCycleStartOffsetVal = recvedLongCycleOffsetVal->choice.ms10240;
+ break;
+ }
+ default :
+ break;
+ }
+}
+
+/*******************************************************************
+ *
+ * @brief Extract configuration from DRX_ConfigRrc
+ * and store the drx configuration in UeCb
+ *
+ * @details
+ *
+ * Function : storeDrxCfgInUeCb
+ *
+ * Functionality: Store drx configuration in UeCb
+ *
+ * @params[in] (struct DRX_ConfigRrc *setup, DrxCfg *drxCfg)
+ *
+ * @return void
+ * ****************************************************************/
+void storeDrxCfgInUeCb(struct DRX_ConfigRrc *drxSetup, DrxCfg *drxCfg)
+{
+ switch(drxSetup->drx_onDurationTimer.present)
+ {
+ case DRX_ConfigRrc__drx_onDurationTimer_PR_NOTHING:
+ break;
+ case DRX_ConfigRrc__drx_onDurationTimer_PR_milliSeconds:
+ {
+ drxCfg->drxOnDurationTimer.onDurationTimerValInMs = true;
+ drxCfg->drxOnDurationTimer.onDurationtimerValue.milliSeconds=drxSetup->drx_onDurationTimer.choice.milliSeconds;
+ break;
+ }
+ case DRX_ConfigRrc__drx_onDurationTimer_PR_subMilliSeconds:
+ {
+ drxCfg->drxOnDurationTimer.onDurationTimerValInMs = false;
+ drxCfg->drxOnDurationTimer.onDurationtimerValue.subMilliSeconds = drxSetup->drx_onDurationTimer.choice.subMilliSeconds;
+ break;
+ }
+ }
+ fillLongCycleOffsetValue(&drxCfg->drxLongCycleStartOffset, &drxSetup->drx_LongCycleStartOffset);
+ drxCfg->drxInactivityTimer = drxSetup->drx_InactivityTimer;
+ drxCfg->drxHarqRttTimerDl = drxSetup->drx_HARQ_RTT_TimerDL;
+ drxCfg->drxHarqRttTimerUl = drxSetup->drx_HARQ_RTT_TimerUL;
+ drxCfg->drxRetransmissionTimerDl = drxSetup->drx_RetransmissionTimerDL;
+ drxCfg->drxRetransmissionTimerUl = drxSetup->drx_RetransmissionTimerUL;
+ drxCfg->drxSlotOffset = drxSetup->drx_SlotOffset;
+ if(drxSetup->shortDRX)
+ {
+ drxCfg->shortDrxPres=true;
+ drxCfg->shortDrx.drxShortCycle = drxSetup->shortDRX->drx_ShortCycle;
+ drxCfg->shortDrx.drxShortCycleTimer = drxSetup->shortDRX->drx_ShortCycleTimer;
+ }
+ else
+ drxCfg->shortDrxPres=false;
+}
+#endif
+
/*******************************************************************
*
* @brief Extract configuration from CellGroupConfig
RLC_BearerConfig_t *rlcCfg = NULLP;
RLC_Config_t *rlcLcCfg = NULLP;
LogicalChannelConfig_t *macLcCfg = NULLP;
+#ifdef NR_DRX
+ DrxCfg drxCfg;
+#endif
if(ueCb == NULLP)
{
return RFAILED;
}
+#ifdef NR_DRX
+ if(cellGrpCfg->mac_CellGroupConfig)
+ {
+ if(cellGrpCfg->mac_CellGroupConfig->drx_ConfigRrc)
+ {
+ switch(cellGrpCfg->mac_CellGroupConfig->drx_ConfigRrc->present)
+ {
+ case MAC_CellGroupConfig__drx_ConfigRrc_PR_NOTHING:
+ break;
+
+ case MAC_CellGroupConfig__drx_ConfigRrc_PR_setup:
+ {
+ if(cellGrpCfg->mac_CellGroupConfig->drx_ConfigRrc->choice.setup)
+ {
+ ueCb->drxCfgPresent = true;
+ storeDrxCfgInUeCb(cellGrpCfg->mac_CellGroupConfig->drx_ConfigRrc->choice.setup, &ueCb->drxCfg);
+ }
+ break;
+ }
+
+ case MAC_CellGroupConfig__drx_ConfigRrc_PR_release:
+ break;
+ }
+ }
+ }
+#endif
+
for(rbIdx = 0; rbIdx < cellGrpCfg->rlc_BearerToAddModList->list.count; rbIdx++)
{
srbFound = false;
cellGrpCfgMsg = &cellGrpCfg;
memset(cellGrpCfgMsg, 0, sizeof(CellGroupConfigRrc_t));
- rval = aper_decode(0, &asn_DEF_CellGroupConfigRrc, (void **)&cellGrpCfgMsg, rrcCont.buf, rrcCont.size, 0, 0);
+ rval = uper_decode(0, &asn_DEF_CellGroupConfigRrc, (void **)&cellGrpCfgMsg, rrcCont.buf, rrcCont.size, 0, 0);
if(rval.code == RC_FAIL || rval.code == RC_WMORE)
{
- DU_LOG("\nERROR --> F1AP : ASN decode failed");
+ DU_LOG("\nERROR --> F1AP : ASN decode failed in extractDuToCuRrcCont");
return RFAILED;
}
printf("\n");
return RFAILED;
}
- if(hoInProgress)
+ if(hoInProgress == Inter_DU_HO)
drbQos->qoS_Characteristics.choice.non_Dynamic_5QI->fiveQI = qosInfo->nonDynFiveQI ;
- else
+ else if(hoInProgress == false || hoInProgress == Xn_Based_Inter_CU_HO)
{
/*FiveQI*/
if(actionType == ProtocolIE_ID_id_DRBs_ToBeModified_Item)
drbQos->nGRANallocationRetentionPriority.pre_emptionCapability = qosInfo->preemptionCapability;
drbQos->nGRANallocationRetentionPriority.pre_emptionVulnerability = qosInfo->preemptionVulnerability;
}
- else
+ else if((hoInProgress == false) || (hoInProgress == Xn_Based_Inter_CU_HO))
{
drbQos->nGRANallocationRetentionPriority.priorityLevel = PriorityLevel_lowest;
drbQos->nGRANallocationRetentionPriority.pre_emptionCapability = Pre_emptionCapability_may_trigger_pre_emption;
uint8_t BuildSNSSAI(DrbInfo *drbInfo, SNSSAI_t *snssai, Snssai *snssaiToCopy, bool hoInProgress)
{
/*SNSSAI*/
+ /* In case of non-HO UE context creation and Xn Based HO, DRB's SNSSAI
+ * configuration is not known beforehand. In these 2 case, the following
+ * condition will hit */
+ if(!hoInProgress || (hoInProgress == Xn_Based_Inter_CU_HO))
+ drbInfo->snssai = snssaiToCopy;
+
/*ssT*/
snssai->sST.size = sizeof(uint8_t);
CU_ALLOC(snssai->sST.buf, snssai->sST.size);
{
return RFAILED;
}
- if(!hoInProgress)
- memcpy(snssai->sST.buf, &snssaiToCopy->sst, snssai->sST.size);
- else
- memcpy(snssai->sST.buf, &drbInfo->snssai->sst, snssai->sST.size);
+ memcpy(snssai->sST.buf, &drbInfo->snssai->sst, snssai->sST.size);
/*sD*/
CU_ALLOC(snssai->sD, sizeof(OCTET_STRING_t));
{
return RFAILED;
}
- if(!hoInProgress)
- memcpy(snssai->sD->buf, snssaiToCopy->sd, snssai->sD->size);
- else
- memcpy(snssai->sD->buf, drbInfo->snssai->sd, snssai->sD->size);
+ memcpy(snssai->sD->buf, drbInfo->snssai->sd, snssai->sD->size);
- if(!hoInProgress)
- drbInfo->snssai = snssaiToCopy;
return ROK;
}/*End of BuildSNSSAI*/
uint8_t ret = ROK, idx = 0, flowCnt = 0, flowIdx = 0;
FlowsMapped *qosFlow;
- if(!hoInProgress)
+ /* In case of non-HO UE context creation and Xn Based HO, DRB's SNSSAI
+ * configuration is not known beforehand. In these 2 case, the following
+ * condition will hit */
+ if(!hoInProgress || (hoInProgress == Xn_Based_Inter_CU_HO))
flowCnt = 1;
else
flowCnt = drbInfo->numFlowMap;
+
flowMap->list.count = flowCnt;
flowMap->list.size = flowCnt * sizeof(Flows_Mapped_To_DRB_Item_t *);
CU_ALLOC(flowMap->list.array,flowMap->list.size);
return RFAILED;
}
- if(!hoInProgress)
+ if(!hoInProgress || (hoInProgress == Xn_Based_Inter_CU_HO))
{
flowMap->list.array[idx]->qoSFlowIdentifier = 0;
if(actionType == ProtocolIE_ID_id_DRBs_ToBeModified_Item)
return RFAILED;
}
- if((!hoInProgress) && (actionType != ProtocolIE_ID_id_DRBs_ToBeModified_Item))
+ if(((!hoInProgress) && (actionType != ProtocolIE_ID_id_DRBs_ToBeModified_Item)) || (hoInProgress == Xn_Based_Inter_CU_HO))
drbInfo->numFlowMap++;
}
return ROK;
return RFAILED;
}
- if(!hoInProgress)
+ if((!hoInProgress) || (hoInProgress == Xn_Based_Inter_CU_HO))
{
/* NOTE: Below IP address must be changed if running on different IP configuration */
ulInfo->list.array[idx]->uLUPTNLInformation.choice.gTPTunnel->transportLayerAddress.buf[0] = 192;
return RFAILED;
}
- if(!hoInProgress)
+ if((!hoInProgress) || (hoInProgress == Xn_Based_Inter_CU_HO))
{
ulInfo->list.array[idx]->uLUPTNLInformation.choice.gTPTunnel->gTP_TEID.buf[0] = 0;
ulInfo->list.array[idx]->uLUPTNLInformation.choice.gTPTunnel->gTP_TEID.buf[1] = 0;
choice_extension->value.choice.DRB_Information.dRB_QoS, ProtocolIE_ID_id_DRBs_ToBeSetup_Item, PDU_SESSION_ID_1, FALSE);
else
BuildQOSInforet = BuildQOSInfo(&ueCb->drbList[idx].qos, &drbSetItem->qoSInformation.choice.\
- choice_extension->value.choice.DRB_Information.dRB_QoS, ProtocolIE_ID_id_DRBs_ToBeSetup_Item, PDU_SESSION_ID_1, TRUE);
+ choice_extension->value.choice.DRB_Information.dRB_QoS, ProtocolIE_ID_id_DRBs_ToBeSetup_Item, PDU_SESSION_ID_1, ueCb->hoInfo.HOType);
if(BuildQOSInforet != ROK)
{
DU_LOG("\nERROR --> F1AP : Failed to build QOS Info in BuildDRBSetup");
choice_extension->value.choice.DRB_Information.sNSSAI, cuCb.snssaiList[snssaiIdx], FALSE);
else
BuildSNSSAIret = BuildSNSSAI(&ueCb->drbList[idx], &drbSetItem->qoSInformation.choice.\
- choice_extension->value.choice.DRB_Information.sNSSAI, NULLP, TRUE);
+ choice_extension->value.choice.DRB_Information.sNSSAI, cuCb.snssaiList[snssaiIdx], ueCb->hoInfo.HOType);
if(BuildSNSSAIret != ROK)
{
DU_LOG("\nERROR --> F1AP : Failed to build SNSSAI Info in BuildDRBSetup");
value.choice.DRB_Information.flows_Mapped_To_DRB_List, ProtocolIE_ID_id_DRBs_ToBeSetup_Item, FALSE);
else
BuildFlowsMapret = BuildFlowsMap(&ueCb->drbList[idx], &drbSetItem->qoSInformation.choice.choice_extension->\
- value.choice.DRB_Information.flows_Mapped_To_DRB_List, ProtocolIE_ID_id_DRBs_ToBeSetup_Item, TRUE);
+ value.choice.DRB_Information.flows_Mapped_To_DRB_List, ProtocolIE_ID_id_DRBs_ToBeSetup_Item, ueCb->hoInfo.HOType);
if(BuildFlowsMapret != ROK)
{
DU_LOG("\nERROR --> F1AP : Failed to build Flow Map Info in BuildDRBSetup");
FALSE);
else
BuildULTnlInforet = BuildULTnlInfo(duId, &ueCb->drbList[idx].ulUpTnlInfo, &drbSetItem->uLUPTNLInformation_ToBeSetup_List,\
- TRUE);
+ ueCb->hoInfo.HOType);
if(BuildULTnlInforet != ROK)
{
DU_LOG("\nERROR --> F1AP : Failed to build tunnel Info in BuildDRBSetup");
}
/*RLCMode*/
- if(ueCb->state != UE_HANDOVER_IN_PROGRESS)
+ if((ueCb->state != UE_HANDOVER_IN_PROGRESS) || (ueCb->hoInfo.HOType == Xn_Based_Inter_CU_HO))
{
drbSetItem->rLCMode = RLCMode_rlc_um_bidirectional;
ueCb->drbList[ueCb->numDrb].rlcMode = drbSetItem->rLCMode;
* ****************************************************************/
uint8_t BuildMacCellGrpCfg(MAC_CellGroupConfig_t *macCellGrpCfg)
{
- macCellGrpCfg->drx_Config = NULLP;
+ macCellGrpCfg->drx_ConfigRrc = NULLP;
macCellGrpCfg->schedulingRequestConfig = NULLP;
CU_ALLOC(macCellGrpCfg->schedulingRequestConfig, sizeof(struct SchedulingRequestConfig));
if(!macCellGrpCfg->schedulingRequestConfig)
xer_fprint(stdout, &asn_DEF_CellGroupConfigRrc, &cellGrpCfg);
cmMemset((uint8_t *)encBuf, 0, ENC_BUF_MAX_LEN);
encBufSize = 0;
- encRetVal = aper_encode(&asn_DEF_CellGroupConfigRrc, 0, &cellGrpCfg, PrepFinalEncBuf, encBuf);
+ encRetVal = uper_encode(&asn_DEF_CellGroupConfigRrc, 0, &cellGrpCfg, PrepFinalEncBuf, encBuf);
/* Encode results */
if(encRetVal.encoded == ENCODE_FAIL)
{
xer_fprint(stdout, &asn_DEF_UE_NR_Capability, &ueNrCap);
cmMemset((uint8_t *)encBuf, 0, ENC_BUF_MAX_LEN);
encBufSize = 0;
- encRetVal = aper_encode(&asn_DEF_UE_NR_Capability, 0, &ueNrCap, PrepFinalEncBuf, encBuf);
+ encRetVal = uper_encode(&asn_DEF_UE_NR_Capability, 0, &ueNrCap, PrepFinalEncBuf, encBuf);
/* Encode results */
if(encRetVal.encoded == ENCODE_FAIL)
xer_fprint(stdout, &asn_DEF_UE_CapabilityRAT_ContainerListRRC, &ueCapablityList);
cmMemset((uint8_t *)encBuf, 0, ENC_BUF_MAX_LEN);
encBufSize = 0;
- encRetVal = aper_encode(&asn_DEF_UE_CapabilityRAT_ContainerListRRC, 0, \
+ encRetVal = uper_encode(&asn_DEF_UE_CapabilityRAT_ContainerListRRC, 0, \
&ueCapablityList, PrepFinalEncBuf, encBuf);
/* Encode results */
xer_fprint(stdout, &asn_DEF_MeasurementTimingConfigurationRrc, &measTimingConfig);
cmMemset((uint8_t *)encBuf, 0, ENC_BUF_MAX_LEN);
encBufSize = 0;
- encRetVal = aper_encode(&asn_DEF_MeasurementTimingConfigurationRrc, 0, &measTimingConfig, PrepFinalEncBuf, encBuf);
+ encRetVal = uper_encode(&asn_DEF_MeasurementTimingConfigurationRrc, 0, &measTimingConfig, PrepFinalEncBuf, encBuf);
/* Encode results */
if(encRetVal.encoded == ENCODE_FAIL)
/* RSRQ offset for SSB */
CU_ALLOC(measObject->offsetMO.rsrqOffsetSSB, sizeof(Q_OffsetRange_t));
- if(!measObject->offsetMO.rsrpOffsetSSB)
+ if(!measObject->offsetMO.rsrqOffsetSSB)
{
DU_LOG("\nERROR --> F1AP: Memory allocation failed for SSB RSRQ offset in fillMeasObjToAddModList");
return RFAILED;
xer_fprint(stdout, &asn_DEF_RRCReconfiguration, rrcReconfig);
cmMemset((uint8_t *)encBuf, 0, ENC_BUF_MAX_LEN);
encBufSize = 0;
- encRetVal = aper_encode(&asn_DEF_RRCReconfiguration, 0, rrcReconfig, PrepFinalEncBuf, encBuf);
+ encRetVal = uper_encode(&asn_DEF_RRCReconfiguration, 0, rrcReconfig, PrepFinalEncBuf, encBuf);
/* Encode results */
if(encRetVal.encoded == ENCODE_FAIL)
xer_fprint(stdout, &asn_DEF_HandoverPreparationInformationRrc, &hoPrepInfo);
cmMemset((uint8_t *)encBuf, 0, ENC_BUF_MAX_LEN);
encBufSize = 0;
- encRetVal = aper_encode(&asn_DEF_HandoverPreparationInformationRrc, 0, \
+ encRetVal = uper_encode(&asn_DEF_HandoverPreparationInformationRrc, 0, \
&hoPrepInfo, PrepFinalEncBuf, encBuf);
/* Encode results */
uint8_t ret = ROK;
uint8_t idx;
- /* UE Capabulity RAT Container List */
- CU_ALLOC(rrcMsg->uE_CapabilityRAT_ContainerList, sizeof(UE_CapabilityRAT_ContainerList_t));
- if(!rrcMsg->uE_CapabilityRAT_ContainerList)
+ if((ueCb->state != UE_HANDOVER_IN_PROGRESS) || ((ueCb->state == UE_HANDOVER_IN_PROGRESS) && (ueCb->hoInfo.HOType == Inter_DU_HO)))
{
- DU_LOG("\nERROR --> F1AP : Memory allocation for UE capability RAT container list failed");
- return RFAILED;
+ /* UE Capabulity RAT Container List */
+ CU_ALLOC(rrcMsg->uE_CapabilityRAT_ContainerList, sizeof(UE_CapabilityRAT_ContainerList_t));
+ if(!rrcMsg->uE_CapabilityRAT_ContainerList)
+ {
+ DU_LOG("\nERROR --> F1AP : Memory allocation for UE capability RAT container list failed");
+ return RFAILED;
+ }
+ ret = fillUeCapRatContListBuf(rrcMsg->uE_CapabilityRAT_ContainerList);
}
- ret = fillUeCapRatContListBuf(rrcMsg->uE_CapabilityRAT_ContainerList);
+
+#if 0
+
+ /* Commenting this because:
+ * CUToDURRCInformation->MeasConfig contains measurement gap configurations.
+ * Howeever measurement gap is not supported in our code. Measurement Gap will
+ * be required if we want to support inter-RAT handover or handover to
+ * neighbouring cells operating on a different frequency than serving cell.
+ *
+ * In case we plan to use this IE in future, following fixes are required:
+ * As of now, we are filling MeasurementTimingConfigurationRrc_t into rrcMsg->measConfig.
+ * This is incorrect. We must fill MeasConfigRrc_t in rrcMsg->measConfig.
+ * MeasurementTimingConfigurationRrc_t should be filled in
+ * rrcMsg->iE_Extensions->MeasurementTimingConfiguration, if required.
+ */
CU_ALLOC(rrcMsg->measConfig, sizeof(MeasConfig_t));
if(!rrcMsg->measConfig)
return RFAILED;
}
ret = fillMeasTimingConfigBuf(rrcMsg->measConfig);
+#endif
if(ueCb->state == UE_HANDOVER_IN_PROGRESS)
{
}
return ret;
}
-
+/*******************************************************************
+ *
+ * @brief Build the drx cycle
+ *
+ * @details
+ *
+ * Function : BuildDrxCycle
+ *
+ * Functionality: Build drx cycle IE
+ *
+ * @params[in] pointer to DRXCycle_t
+ *
+ * @return ROK - success
+ * RFAILED - failure
+ *
+ ******************************************************************/
+uint8_t BuildDrxCycle(DRXCycle_t *drxCycle)
+{
+ drxCycle->longDRXCycleLength = LongDRXCycleLength_ms80;
+ CU_ALLOC(drxCycle->shortDRXCycleLength, sizeof(ShortDRXCycleLength_t));
+ if(!drxCycle->shortDRXCycleLength)
+ {
+ DU_LOG("\nERROR --> F1AP : Memory allocation failed for shortDRXCycleLength");
+ return RFAILED;
+ }
+ *(drxCycle->shortDRXCycleLength) = ShortDRXCycleLength_ms4;
+
+ CU_ALLOC(drxCycle->shortDRXCycleTimer, sizeof(ShortDRXCycleTimer_t));
+ if(!drxCycle->shortDRXCycleTimer)
+ {
+ DU_LOG("\nERROR --> F1AP : Memory allocation failed for shortDRXCycleTimer");
+ return RFAILED;
+ }
+ *(drxCycle->shortDRXCycleTimer) = 4;
+ return ROK;
+}
/*******************************************************************
*
* @brief Free CuToDuContainer
uint8_t elementCnt;
uint8_t idx, idx1, bufLen, duIdx;
uint32_t spCellId;
+ uint32_t targetDuId;
DuDb *targetDuDb = NULLP;
F1AP_PDU_t *f1apMsg = NULLP;
UEContextSetupRequest_t *ueSetReq = NULLP;
if(ueCb->state == UE_HANDOVER_IN_PROGRESS)
elementCnt = 7;
else
+ {
+#ifdef NR_DRX
+ elementCnt = 12;
+#else
elementCnt = 11;
+#endif
+ }
ueSetReq->protocolIEs.list.count = elementCnt;
ueSetReq->protocolIEs.list.size = elementCnt * sizeof(UEContextSetupRequestIEs_t *);
ueSetReq->protocolIEs.list.array[idx]->id = ProtocolIE_ID_id_SpCell_ID;
ueSetReq->protocolIEs.list.array[idx]->criticality = Criticality_reject;
ueSetReq->protocolIEs.list.array[idx]->value.present = UEContextSetupRequestIEs__value_PR_NRCGI;
+
+ /* Spec 38.473 Sec 9.2.2.1 : For handover case, this IE shall be considered as target cell. */
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);
+ if(ueCb->hoInfo.HOType == Inter_DU_HO)
+ targetDuId = ueCb->hoInfo.tgtNodeId;
+ else
+ targetDuId = duId;
+
+ SEARCH_DU_DB(duIdx, targetDuId, targetDuDb);
/* Since we are supporting only one cell per DU, accessing 0th index to
* get target cell info */
spCellId = targetDuDb->cellCb[0].nrCellId;
}
else
spCellId = ueCb->cellCb->nrCellId;
+
Nrcgiret = BuildNrcgi(&ueSetReq->protocolIEs.list.array[idx]->value.choice.NRCGI, spCellId);
if(Nrcgiret != ROK)
{
if(ueCb->state != UE_HANDOVER_IN_PROGRESS)
{
+ /*Drx cycle*/
+#ifdef NR_DRX
+ idx++;
+ ueSetReq->protocolIEs.list.array[idx]->id = ProtocolIE_ID_id_DRXCycle;
+ ueSetReq->protocolIEs.list.array[idx]->criticality = Criticality_ignore;
+ ueSetReq->protocolIEs.list.array[idx]->value.present = UEContextSetupRequestIEs__value_PR_DRXCycle;
+ if(BuildDrxCycle(&ueSetReq->protocolIEs.list.array[idx]->value.choice.DRXCycle) != ROK)
+ {
+ DU_LOG("\nERROR --> F1AP : Failed to build drx cycle");
+ break;
+ }
+#endif
/*Special Cells to be SetupList*/
idx++;
ueSetReq->protocolIEs.list.array[idx]->id = ProtocolIE_ID_id_SCell_ToBeSetup_List;
* RFAILED - failure
*
* ****************************************************************/
-uint8_t procUeContextSetupResponse(uint32_t duId, F1AP_PDU_t *f1apMsg)
+uint8_t procUeContextSetupResponse(uint32_t duId, F1AP_PDU_t *f1apMsg, char *recvBuf, MsgLen recvBufLen)
{
uint8_t duIdx = 0, idx = 0, ueIdx = 0, rrcMsgType=0;
uint8_t duUeF1apId = 0, cuUeF1apId = 0;
{
/* Creating UE context in target DU */
memset(ueCb, 0, sizeof(CuUeCb));
- ueCb->cellCb = &duDb->cellCb[0];
- ueCb->gnbDuUeF1apId = duUeF1apId;
- ueCb->gnbCuUeF1apId = cuUeF1apId;
- ueCb->state = UE_HANDOVER_IN_PROGRESS;
- ueCb->hoInfo.targetDuId = duId;
+
+ /* Check if UE is under Inter-CU handover */
+ if(duDb->tempUeCtxtInHo && (duDb->tempUeCtxtInHo->gnbCuUeF1apId == cuUeF1apId))
+ {
+ memcpy(ueCb, duDb->tempUeCtxtInHo, sizeof(CuUeCb));
+ ueCb->gnbDuUeF1apId = duUeF1apId;
+ CU_FREE(duDb->tempUeCtxtInHo, sizeof(CuUeCb));
+ }
+ else
+ {
+ /* In case of Inter DU Handover */
+ ueCb->cellCb = &duDb->cellCb[0];
+ ueCb->gnbDuUeF1apId = duUeF1apId;
+ ueCb->gnbCuUeF1apId = cuUeF1apId;
+ ueCb->state = UE_HANDOVER_IN_PROGRESS;
+ ueCb->hoInfo.HOType = Inter_DU_HO;
+ ueCb->hoInfo.tgtNodeId = duId;
+ }
(duDb->numUe)++;
ueCb->cellCb->ueCb[ueCb->cellCb->numUe] = ueCb;
}
}
- /* If the UE is in handover, UE context modification request is to be sent to
- * source DU once UE context setup response is received from target DU */
- if(ueCb->state == UE_HANDOVER_IN_PROGRESS)
+ if(ueCb->state != UE_HANDOVER_IN_PROGRESS)
{
- DuDb *srcDuDb = NULLP;
- CuUeCb *ueCbInSrcDu = NULLP;
-
- /* Since Source DU Id and DU UE F1AP ID assigned to UE by source DU is not known here, we
- * need to find Source DU and UE CB in source DU using CU UE F1AP ID */
- for(duIdx=0; duIdx < cuCb.numDu; duIdx++)
- {
- /* UE context setup response is received from target DU. Search all
- * DUs to find source DU except this target DU Id.*/
- if(cuCb.duInfo[duIdx].duId != duId)
- {
- for(ueIdx = 0; ueIdx < MAX_NUM_UE; ueIdx++)
- {
- /* Check following:
- * 1. CU UE F1AP ID in srcDU->ueCb should be same as cuUeF1apId
- * received in UE context setup response since CU UE F1AP ID does not
- * change for UE in handover.
- * 2. srcDU->UeCb->uestate should be UE_HANDOVER_IN_PROGRESS
- */
- if((cuCb.duInfo[duIdx].ueCb[ueIdx].gnbCuUeF1apId == cuUeF1apId) &&
- (cuCb.duInfo[duIdx].ueCb[ueIdx].state == UE_HANDOVER_IN_PROGRESS))
- {
- srcDuDb = &cuCb.duInfo[duIdx];
- ueCbInSrcDu = &cuCb.duInfo[duIdx].ueCb[ueIdx];
-
- /* Store source DU info in the new UE context created in
- * tareget DU */
- ueCb->hoInfo.sourceDuId = srcDuDb->duId;
+ ueCb->f1apMsgDb.dlRrcMsgCount++;
+ rrcMsgType = setDlRRCMsgType(ueCb);
- /* Copy the received container to UeCb */
- memcpy(&ueCbInSrcDu->f1apMsgDb.duToCuContainer, duToCuRrcContainer, sizeof(OCTET_STRING_t));
+ DU_LOG("\nINFO --> F1AP: Sending DL RRC MSG for RRC reconfiguration");
+ if(BuildAndSendDLRRCMessageTransfer(duId, ueCb, SRB1, rrcMsgType) != ROK)
+ {
+ DU_LOG("\nINFO --> F1AP: Failed to build and send DL RRC MSG for RRC reconfiguration");
+ return RFAILED;
+ }
+ }
+ else
+ {
+ if(ueCb->hoInfo.HOType == Inter_DU_HO)
+ {
+ /* If the UE is in Inter-DU handover, UE context modification request is to be sent to
+ * source DU once UE context setup response is received from target DU */
+
+ DuDb *srcDuDb = NULLP;
+ CuUeCb *ueCbInSrcDu = NULLP;
- if(BuildAndSendUeContextModificationReq(srcDuDb->duId, ueCbInSrcDu, STOP_DATA_TX) != ROK)
+ /* Since Source DU Id and DU UE F1AP ID assigned to UE by source DU is not known here, we
+ * need to find Source DU and UE CB in source DU using CU UE F1AP ID */
+ for(duIdx=0; duIdx < cuCb.numDu; duIdx++)
+ {
+ /* UE context setup response is received from target DU. Search all
+ * DUs to find source DU except this target DU Id.*/
+ if(cuCb.duInfo[duIdx].duId != duId)
+ {
+ for(ueIdx = 0; ueIdx < MAX_NUM_UE; ueIdx++)
+ {
+ /* Check following:
+ * 1. CU UE F1AP ID in srcDU->ueCb should be same as cuUeF1apId
+ * received in UE context setup response since CU UE F1AP ID does not
+ * change for UE in handover.
+ * 2. srcDU->UeCb->uestate should be UE_HANDOVER_IN_PROGRESS
+ */
+ if((cuCb.duInfo[duIdx].ueCb[ueIdx].gnbCuUeF1apId == cuUeF1apId) &&
+ (cuCb.duInfo[duIdx].ueCb[ueIdx].state == UE_HANDOVER_IN_PROGRESS))
{
- DU_LOG("\nERROR -> F1AP : Failed at BuildAndSendUeContextModificationReq()");
- return RFAILED;
+ srcDuDb = &cuCb.duInfo[duIdx];
+ ueCbInSrcDu = &cuCb.duInfo[duIdx].ueCb[ueIdx];
+
+ /* Store source DU info in the new UE context created in
+ * tareget DU */
+ ueCb->hoInfo.srcNodeId = srcDuDb->duId;
+
+ /* Copy the received container to UeCb */
+ memcpy(&ueCbInSrcDu->f1apMsgDb.duToCuContainer, duToCuRrcContainer, sizeof(OCTET_STRING_t));
+
+ if(BuildAndSendUeContextModificationReq(srcDuDb->duId, ueCbInSrcDu, STOP_DATA_TX) != ROK)
+ {
+ DU_LOG("\nERROR -> F1AP : Failed at BuildAndSendUeContextModificationReq()");
+ return RFAILED;
+ }
+ break;
}
- break;
}
}
+ if(srcDuDb && ueCbInSrcDu)
+ break;
}
- if(srcDuDb && ueCbInSrcDu)
- break;
}
- }
- else
- {
- ueCb->f1apMsgDb.dlRrcMsgCount++;
- rrcMsgType = setDlRRCMsgType(ueCb);
-
- DU_LOG("\nINFO --> F1AP: Sending DL RRC MSG for RRC reconfiguration");
- if(BuildAndSendDLRRCMessageTransfer(duId, ueCb, SRB1, rrcMsgType) != ROK)
+ else if(ueCb->hoInfo.HOType == Xn_Based_Inter_CU_HO)
{
- DU_LOG("\nINFO --> F1AP: Failed to build and send DL RRC MSG for RRC reconfiguration");
- return RFAILED;
+ BuildAndSendHOReqAck(ueCb, duToCuRrcContainer->buf, duToCuRrcContainer->size);
}
}
if(duDb->ueCb[duUeF1apId-1].state == UE_HANDOVER_IN_PROGRESS)
{
- uint8_t ueIdx = 0;
- uint8_t srcDuId = duDb->ueCb[duUeF1apId-1].hoInfo.sourceDuId;
- DuDb *srcDuDb = NULLP;
-
- /* In target DU DB, mark UE as active and delete HO info */
- duDb->ueCb[duUeF1apId-1].state = UE_ACTIVE;
- memset(&duDb->ueCb[duUeF1apId-1].hoInfo, 0, sizeof(HandoverInfo));
-
- /* Release UE context in source DU because the UE is now
- * attached to target DU */
- SEARCH_DU_DB(duIdx, srcDuId, srcDuDb);
- for(ueIdx = 0; ueIdx < srcDuDb->numUe; ueIdx++)
+ if(duDb->ueCb[duUeF1apId-1].hoInfo.HOType == Inter_DU_HO)
{
- if(srcDuDb->ueCb[ueIdx].gnbCuUeF1apId == cuUeF1apId)
+ uint8_t ueIdx = 0;
+ uint8_t srcDuId = duDb->ueCb[duUeF1apId-1].hoInfo.srcNodeId;
+ DuDb *srcDuDb = NULLP;
+
+ /* Release UE context in source DU because the UE is now
+ * attached to target DU */
+ SEARCH_DU_DB(duIdx, srcDuId, srcDuDb);
+ for(ueIdx = 0; ueIdx < srcDuDb->numUe; ueIdx++)
{
- ret = BuildAndSendUeContextReleaseCommand(srcDuId, srcDuDb->ueCb[ueIdx].gnbCuUeF1apId, srcDuDb->ueCb[ueIdx].gnbDuUeF1apId);
- if(ret != ROK)
+ if(srcDuDb->ueCb[ueIdx].gnbCuUeF1apId == cuUeF1apId)
{
- DU_LOG("\nINFO --> F1AP: Failed to build and send UE context release command to source DU Id [%d]", srcDuId);
+ ret = BuildAndSendUeContextReleaseCommand(srcDuId, srcDuDb->ueCb[ueIdx].gnbCuUeF1apId, srcDuDb->ueCb[ueIdx].gnbDuUeF1apId);
+ if(ret != ROK)
+ {
+ DU_LOG("\nINFO --> F1AP: Failed to build and send UE context release command to source DU Id [%d]", srcDuId);
+ }
+ break;
}
- break;
}
}
+ else
+ {
+ BuildAndSendUeContextRelease(&duDb->ueCb[duUeF1apId-1]);
+ }
+
+ /* In target DU DB, mark UE as active and delete HO info */
+ duDb->ueCb[duUeF1apId-1].state = UE_ACTIVE;
+ memset(&duDb->ueCb[duUeF1apId-1].hoInfo, 0, sizeof(HandoverInfo));
return ret;
}
break;
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 Security Mode Command");
- ret = BuildAndSendDLRRCMessageTransfer(duId, ueCb, srbId, rrcMsgType);
- }
- else if(rrcMsgType == 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);
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;
}
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
}
+/*******************************************************************
+*
+* @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
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:
uint8_t ieIdx = 0;
uint8_t elementCnt = 0;
uint8_t ret = RFAILED;
+ uint16_t tmpBufIdx = 0, bufIdx = 0;
CuUeCb *ueCb = (CuUeCb *)cuUeCb;
F1AP_PDU_t *f1apMsg = NULLP;
UEContextModificationRequest_t *ueContextModifyReq = NULLP;
+ RRCContainer_t rrcContainerTmp, *rrcContainer = NULLP;
asn_enc_rval_t encRetVal;
DU_LOG("\nINFO --> F1AP : Building Ue context modification request\n");
while(1)
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)
elementCnt = 3;
else if((action == STOP_DATA_TX) || (action == RESTART_DATA_TX))
- elementCnt = 5;
-
+ {
+ if(ueCb->state != UE_HANDOVER_IN_PROGRESS)
+ elementCnt = 5;
+ else
+ elementCnt = 4;
+ }
+
+#ifdef NR_DRX
+ if(DRX_TO_BE_RELEASE && ueCb->drxCfgPresent)
+ elementCnt++;
+#endif
ueContextModifyReq->protocolIEs.list.count = elementCnt;
ueContextModifyReq->protocolIEs.list.size = elementCnt*sizeof(UEContextModificationRequest_t *);
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)
{
ieIdx++;
ueContextModifyReq->protocolIEs.list.array[ieIdx]->id = ProtocolIE_ID_id_RRCContainer;
ueContextModifyReq->protocolIEs.list.array[ieIdx]->criticality = Criticality_reject;
- ueContextModifyReq->protocolIEs.list.array[ieIdx]->value.present = \
- UEContextModificationRequestIEs__value_PR_RRCContainer;
- if(fillRrcReconfigBuf(ueCb, &ueContextModifyReq->protocolIEs.list.array[ieIdx]->value.choice.RRCContainer, true) != ROK)
+ ueContextModifyReq->protocolIEs.list.array[ieIdx]->value.present = UEContextModificationRequestIEs__value_PR_RRCContainer;
+ if(fillDlDcchRrcMsg(ueCb, &rrcContainerTmp, true) != ROK)
{
DU_LOG( "\nERROR --> F1AP : Failed to fill Rrc reconfiguration buffer");
return RFAILED;
}
+ rrcContainer = &ueContextModifyReq->protocolIEs.list.array[ieIdx]->value.choice.RRCContainer;
+ rrcContainer->size = rrcContainerTmp.size + 2; /* 2 bytes of PDCP SN */
+ CU_ALLOC(rrcContainer->buf, rrcContainer->size);
+ memset(rrcContainer->buf, 0, rrcContainer->size);
+ rrcContainer->buf[0] = 0x00;
+ rrcContainer->buf[1] = ueCb->pdcpSn; //PDCP SN
+ for(bufIdx = 2, tmpBufIdx = 0; bufIdx < rrcContainer->size; bufIdx++, tmpBufIdx++)
+ {
+ rrcContainer->buf[bufIdx] = rrcContainerTmp.buf[tmpBufIdx];
+ }
+
/* RRC delivery status request */
+ if(ueCb->state != UE_HANDOVER_IN_PROGRESS)
+ {
+ ieIdx++;
+ ueContextModifyReq->protocolIEs.list.array[ieIdx]->id = ProtocolIE_ID_id_RRCDeliveryStatusRequest;
+ ueContextModifyReq->protocolIEs.list.array[ieIdx]->criticality = Criticality_ignore;
+ ueContextModifyReq->protocolIEs.list.array[ieIdx]->value.present = UEContextModificationRequestIEs__value_PR_RRCDeliveryStatusRequest;
+ ueContextModifyReq->protocolIEs.list.array[ieIdx]->value.choice.RRCDeliveryStatusRequest = RRCDeliveryStatusRequest_true;
+ }
+ }
+
+#ifdef NR_DRX
+ if(DRX_TO_BE_RELEASE && ueCb->drxCfgPresent)
+ {
+ /* DRX Configuration Indicator */
ieIdx++;
- ueContextModifyReq->protocolIEs.list.array[ieIdx]->id = ProtocolIE_ID_id_RRCDeliveryStatusRequest;
+ ueContextModifyReq->protocolIEs.list.array[ieIdx]->id = ProtocolIE_ID_id_DRXConfigurationIndicator;
ueContextModifyReq->protocolIEs.list.array[ieIdx]->criticality = Criticality_ignore;
- ueContextModifyReq->protocolIEs.list.array[ieIdx]->value.present = UEContextModificationRequestIEs__value_PR_RRCDeliveryStatusRequest;
- ueContextModifyReq->protocolIEs.list.array[ieIdx]->value.choice.RRCDeliveryStatusRequest = RRCDeliveryStatusRequest_true;
+ ueContextModifyReq->protocolIEs.list.array[ieIdx]->value.present = UEContextModificationRequestIEs__value_PR_DRXConfigurationIndicator;
+ ueContextModifyReq->protocolIEs.list.array[ieIdx]->value.choice.DRXConfigurationIndicator = DRXConfigurationIndicator_release;
+ ueCb->drxCfgPresent = false;
+ memset(&ueCb->drxCfg, 0, sizeof(DrxCfg));
}
+#endif
xer_fprint(stdout, &asn_DEF_F1AP_PDU, f1apMsg);
if(ueCb->state != UE_HANDOVER_IN_PROGRESS)
{
- /* extracting teId */
- teId = extractTeId(&drbItemIe->value.choice.DRBs_SetupMod_Item.dLUPTNLInformation_ToBeSetup_List);
- if(teId > 0)
- {
- if(addDrbTunnels(duId, teId)== ROK)
- {
- DU_LOG("\nDEBUG --> EGTP: Tunnel Added for TeId %d", teId);
- }
- }
- else
- return RFAILED;
+ /* extracting teId */
+ teId = extractTeId(&drbItemIe->value.choice.DRBs_SetupMod_Item.dLUPTNLInformation_ToBeSetup_List);
+ if(teId > 0)
+ {
+ if(addDrbTunnels(duId, teId)== ROK)
+ {
+ DU_LOG("\nDEBUG --> EGTP: Tunnel Added for TeId %d", teId);
+ }
+ }
+ else
+ return RFAILED;
}
}
}
* 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;
SEARCH_DU_DB(duIdx, duId, duDb);
ueCtxtModRsp = &f1apMsg->choice.successfulOutcome->value.choice.UEContextModificationResponse;
+
+ /* In case of Inter-CU Handover request received from peer CU */
+ if(duDb->tempUeCtxtInHo)
+ ueCb = duDb->tempUeCtxtInHo;
for(idx=0; idx < ueCtxtModRsp->protocolIEs.list.count; idx++)
{
{
case ProtocolIE_ID_id_gNB_CU_UE_F1AP_ID:
{
- cuUeF1apId = ueCtxtModRsp->protocolIEs.list.array[idx]->value.choice.GNB_CU_UE_F1AP_ID;
+ if(ueCb == NULLP)
+ {
+ cuUeF1apId = ueCtxtModRsp->protocolIEs.list.array[idx]->value.choice.GNB_CU_UE_F1AP_ID;
+ }
+ else
+ {
+ /* In case of Inter-CU Handover request received from peer CU */
+ cuUeF1apId = ueCb->gnbCuUeF1apId;
+ }
break;
}
case ProtocolIE_ID_id_gNB_DU_UE_F1AP_ID:
{
- duUeF1apId = ueCtxtModRsp->protocolIEs.list.array[idx]->value.choice.GNB_DU_UE_F1AP_ID;
- ueCb = &duDb->ueCb[duUeF1apId-1];
+ if(!ueCb)
+ {
+ duUeF1apId = ueCtxtModRsp->protocolIEs.list.array[idx]->value.choice.GNB_DU_UE_F1AP_ID;
+ ueCb = &duDb->ueCb[duUeF1apId-1];
+
+ /* In case UE context modification response is received at source GNB CU from source GNB DU
+ * for a UE in handover, send HO request to target GNB only if not sent already.
+ * If HO Req is already sent to target GNB, and an HO Req Ack is received, then
+ * ueCb->hoInfo.cuUeF1apIdTgt will be non-zero
+ */
+ if((ueCb->state == UE_HANDOVER_IN_PROGRESS) && (ueCb->hoInfo.HOType == Xn_Based_Inter_CU_HO) && \
+ (ueCb->hoInfo.cuUeF1apIdTgt == 0))
+ {
+ BuildAndSendHOReq(ueCb, recvBuf, recvBufLen);
+ }
+ }
break;
}
case ProtocolIE_ID_id_DRBs_SetupMod_List:
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);
if(ueCb->state == UE_HANDOVER_IN_PROGRESS)
{
uint8_t ueIdx = 0;
+ uint8_t tgtDuId = 0;
DuDb *tgtDuDb = NULLP;
CuUeCb *ueCbInTgtDu = NULLP;
- SEARCH_DU_DB(duIdx, ueCb->hoInfo.targetDuId, tgtDuDb);
+ if(ueCb->hoInfo.HOType == Inter_DU_HO)
+ {
+ tgtDuId = ueCb->hoInfo.tgtNodeId;
+ }
+ else if (ueCb->hoInfo.HOType == Xn_Based_Inter_CU_HO)
+ {
+ tgtDuId = duId;
+ }
+
+ SEARCH_DU_DB(duIdx, tgtDuId, tgtDuDb);
if(tgtDuDb)
{
/* Since DU UE F1AP ID assigned by target DU to this UE in handover is
}
}
- /* If UE context is not found in Target DU DU, send UE context setup
+ /* If UE context is not found in Target DU, send UE context setup
* request */
if(ueCbInTgtDu == NULLP)
{
- if((BuildAndSendUeContextSetupReq(ueCb->hoInfo.targetDuId, ueCb)) != ROK)
+ if((BuildAndSendUeContextSetupReq(tgtDuId, ueCb)) != ROK)
{
DU_LOG("\nERROR -> F1AP : Failed at BuildAndSendUeContextSetupReq");
return RFAILED;
}
}
}
-
+
+#ifdef START_DL_UL_DATA
+ startDlData();
+#endif
+
return ROK;
}
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++)
{
if(duDb == NULLP)
{
duDb = &cuCb.duInfo[cuCb.numDu];
- memset(duDb, 0, sizeof(DuDb));
- duDb->duId = duId;
cuCb.numDu++;
- *destDuId = duId;
}
- else
- return;
+ memset(duDb, 0, sizeof(DuDb));
+ duDb->duId = duId;
+ *destDuId = duId;
break;
}
case ProtocolIE_ID_id_gNB_DU_Name:
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)
{
/*******************************************************************
*
- * @brief Handles received F1AP message and sends back response
+ * @brief Decode received character string into F1AP message
*
* @details
*
*
* Functionality:
* - Decodes received F1AP control message
- * - Prepares response message, encodes and sends to SCTP
*
* @params[in]
* @return ROK - success
* RFAILED - failure
*
* ****************************************************************/
-void F1APMsgHdlr(uint32_t *duId, Buffer *mBuf)
+uint8_t F1APDecodeMsg(F1AP_PDU_t *f1apMsg, Buffer *mBuf, char **recvBuf, MsgLen *recvBufLen)
{
int i;
- char *recvBuf;
MsgLen copyCnt;
- MsgLen recvBufLen;
- F1AP_PDU_t *f1apMsg = NULLP;
asn_dec_rval_t rval; /* Decoder return value */
- F1AP_PDU_t f1apasnmsg ;
-
- DU_LOG("\nINFO --> F1AP : Received F1AP message buffer");
- 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)
+ ODU_GET_MSG_LEN(mBuf, recvBufLen);
+ CU_ALLOC(*recvBuf, (Size)(*recvBufLen));
+ if(*recvBuf == NULLP)
{
DU_LOG("\nERROR --> F1AP : Memory allocation failed");
- return;
+ return RFAILED;
}
- if(ODU_COPY_MSG_TO_FIX_BUF(mBuf, 0, recvBufLen, (Data *)recvBuf, ©Cnt) != ROK)
+ if(ODU_COPY_MSG_TO_FIX_BUF(mBuf, 0, *recvBufLen, (Data *)*recvBuf, ©Cnt) != ROK)
{
DU_LOG("\nERROR --> F1AP : Failed while copying %d", copyCnt);
- return;
+ return RFAILED;
}
- DU_LOG("\nDEBUG --> F1AP : Received flat buffer to be decoded : ");
- for(i=0; i< recvBufLen; i++)
+ DU_LOG("\nDEBUG --> F1AP : Received flat buffer to be decoded : \n");
+ for(i=0; i< *recvBufLen; i++)
{
- DU_LOG("%x",recvBuf[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);
-
+ rval = aper_decode(0, &asn_DEF_F1AP_PDU, (void **)&f1apMsg, *recvBuf, *recvBufLen, 0, 0);
if(rval.code == RC_FAIL || rval.code == RC_WMORE)
{
DU_LOG("\nERROR --> F1AP : ASN decode failed");
- return;
+ return RFAILED;
}
+
+ /* Printing the decoded F1AP PDU */
DU_LOG("\n");
xer_fprint(stdout, &asn_DEF_F1AP_PDU, f1apMsg);
+ return ROK;
+}
+
+/*******************************************************************
+ *
+ * @brief Handles received F1AP message and sends back response
+ *
+ * @details
+ *
+ * Function : F1APMsgHdlr
+ *
+ * Functionality:
+ * - Decodes received F1AP control message
+ * - Prepares response message, encodes and sends to SCTP
+ *
+ * @params[in]
+ * @return ROK - success
+ * RFAILED - failure
+ *
+ * ****************************************************************/
+void F1APMsgHdlr(uint32_t *duId, Buffer *mBuf)
+{
+ char *recvBuf;
+ MsgLen recvBufLen;
+ F1AP_PDU_t *f1apMsg = NULLP;
+ F1AP_PDU_t f1apasnmsg ;
+
+ DU_LOG("\nINFO --> F1AP : Received F1AP message buffer");
+ ODU_PRINT_MSG(mBuf, 0,0);
+
+ f1apMsg = &f1apasnmsg;
+ memset(f1apMsg, 0, sizeof(F1AP_PDU_t));
+ if(F1APDecodeMsg(f1apMsg, mBuf, &recvBuf, &recvBufLen) != ROK)
+ {
+ DU_LOG("\nERROR --> F1AP : F1AP PDU decode failed");
+ return;
+ }
switch(f1apMsg->present)
{
case SuccessfulOutcome__value_PR_UEContextSetupResponse:
{
DU_LOG("\nINFO --> F1AP : UE ContextSetupResponse received");
- procUeContextSetupResponse(*duId, f1apMsg);
+ procUeContextSetupResponse(*duId, f1apMsg, recvBuf, recvBufLen);
break;
}
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:
}
}/* End of switch(f1apMsg->present) */
+ CU_FREE(recvBuf, (Size)(recvBufLen));
} /* End of F1APMsgHdlr */
/**********************************************************************