Merge remote-tracking branch 'origin/int-f1-ue-ctxt-modif' into integration_2023_w21
This commit is contained in:
@@ -84,7 +84,7 @@ int nr_rlc_get_available_tx_space(const rnti_t rntiP, const logical_chan_id_t ch
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
void rrc_gNB_generate_dedicatedRRCReconfiguration(const protocol_ctxt_t *const ctxt_pP, rrc_gNB_ue_context_t *ue_context_pP, NR_CellGroupConfig_t *cell_groupConfig_from_DU)
|
void rrc_gNB_generate_dedicatedRRCReconfiguration(const protocol_ctxt_t *const ctxt_pP, rrc_gNB_ue_context_t *ue_context_pP)
|
||||||
{
|
{
|
||||||
abort();
|
abort();
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -46,8 +46,8 @@ MESSAGE_DEF(F1AP_DL_RRC_MESSAGE , MESSAGE_PRIORITY_MED, f1ap_dl_rrc
|
|||||||
//MESSAGE_DEF(F1AP_INITIAL_CONTEXT_SETUP_REQ , MESSAGE_PRIORITY_MED, f1ap_initial_context_setup_req_t , f1ap_initial_context_setup_req )
|
//MESSAGE_DEF(F1AP_INITIAL_CONTEXT_SETUP_REQ , MESSAGE_PRIORITY_MED, f1ap_initial_context_setup_req_t , f1ap_initial_context_setup_req )
|
||||||
MESSAGE_DEF(F1AP_UE_CONTEXT_SETUP_REQ, MESSAGE_PRIORITY_MED, f1ap_ue_context_setup_t, f1ap_ue_context_setup_req)
|
MESSAGE_DEF(F1AP_UE_CONTEXT_SETUP_REQ, MESSAGE_PRIORITY_MED, f1ap_ue_context_setup_t, f1ap_ue_context_setup_req)
|
||||||
MESSAGE_DEF(F1AP_UE_CONTEXT_SETUP_RESP, MESSAGE_PRIORITY_MED, f1ap_ue_context_setup_t, f1ap_ue_context_setup_resp)
|
MESSAGE_DEF(F1AP_UE_CONTEXT_SETUP_RESP, MESSAGE_PRIORITY_MED, f1ap_ue_context_setup_t, f1ap_ue_context_setup_resp)
|
||||||
MESSAGE_DEF(F1AP_UE_CONTEXT_MODIFICATION_REQ, MESSAGE_PRIORITY_MED, f1ap_ue_context_setup_t, f1ap_ue_context_modification_req)
|
MESSAGE_DEF(F1AP_UE_CONTEXT_MODIFICATION_REQ, MESSAGE_PRIORITY_MED, f1ap_ue_context_modif_req_t, f1ap_ue_context_modification_req)
|
||||||
MESSAGE_DEF(F1AP_UE_CONTEXT_MODIFICATION_RESP, MESSAGE_PRIORITY_MED, f1ap_ue_context_setup_t, f1ap_ue_context_modification_resp)
|
MESSAGE_DEF(F1AP_UE_CONTEXT_MODIFICATION_RESP, MESSAGE_PRIORITY_MED, f1ap_ue_context_modif_resp_t, f1ap_ue_context_modification_resp)
|
||||||
|
|
||||||
/* CU -> DU*/
|
/* CU -> DU*/
|
||||||
MESSAGE_DEF(F1AP_PAGING_IND, MESSAGE_PRIORITY_MED, f1ap_paging_ind_t, f1ap_paging_ind)
|
MESSAGE_DEF(F1AP_PAGING_IND, MESSAGE_PRIORITY_MED, f1ap_paging_ind_t, f1ap_paging_ind)
|
||||||
|
|||||||
@@ -341,7 +341,6 @@ typedef struct f1ap_drb_to_be_setup_s {
|
|||||||
|
|
||||||
typedef struct f1ap_srb_to_be_setup_s {
|
typedef struct f1ap_srb_to_be_setup_s {
|
||||||
long srb_id;
|
long srb_id;
|
||||||
rlc_mode_t rlc_mode;
|
|
||||||
uint8_t lcid;
|
uint8_t lcid;
|
||||||
} f1ap_srb_to_be_setup_t;
|
} f1ap_srb_to_be_setup_t;
|
||||||
|
|
||||||
@@ -409,7 +408,7 @@ typedef struct f1ap_ue_context_setup_s {
|
|||||||
ReconfigurationCompl_t ReconfigComplOutcome;
|
ReconfigurationCompl_t ReconfigComplOutcome;
|
||||||
uint8_t *rrc_container;
|
uint8_t *rrc_container;
|
||||||
int rrc_container_length;
|
int rrc_container_length;
|
||||||
} f1ap_ue_context_setup_t;
|
} f1ap_ue_context_setup_t, f1ap_ue_context_modif_req_t, f1ap_ue_context_modif_resp_t;
|
||||||
|
|
||||||
typedef enum F1ap_Cause_e {
|
typedef enum F1ap_Cause_e {
|
||||||
F1AP_CAUSE_NOTHING, /* No components present */
|
F1AP_CAUSE_NOTHING, /* No components present */
|
||||||
|
|||||||
@@ -171,7 +171,7 @@ void *F1AP_CU_task(void *arg) {
|
|||||||
|
|
||||||
case F1AP_UE_CONTEXT_MODIFICATION_REQ:
|
case F1AP_UE_CONTEXT_MODIFICATION_REQ:
|
||||||
CU_send_UE_CONTEXT_MODIFICATION_REQUEST(ITTI_MSG_DESTINATION_INSTANCE(received_msg),
|
CU_send_UE_CONTEXT_MODIFICATION_REQUEST(ITTI_MSG_DESTINATION_INSTANCE(received_msg),
|
||||||
&F1AP_UE_CONTEXT_SETUP_REQ(received_msg));
|
&F1AP_UE_CONTEXT_MODIFICATION_REQ(received_msg));
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case F1AP_UE_CONTEXT_RELEASE_CMD: // from rrc
|
case F1AP_UE_CONTEXT_RELEASE_CMD: // from rrc
|
||||||
|
|||||||
@@ -981,7 +981,8 @@ int CU_handle_UE_CONTEXT_RELEASE_COMPLETE(instance_t instance,
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
int CU_send_UE_CONTEXT_MODIFICATION_REQUEST(instance_t instance, f1ap_ue_context_setup_t *f1ap_ue_context_modification_req) {
|
int CU_send_UE_CONTEXT_MODIFICATION_REQUEST(instance_t instance, f1ap_ue_context_modif_req_t *f1ap_ue_context_modification_req)
|
||||||
|
{
|
||||||
F1AP_F1AP_PDU_t pdu= {0};
|
F1AP_F1AP_PDU_t pdu= {0};
|
||||||
F1AP_UEContextModificationRequest_t *out;
|
F1AP_UEContextModificationRequest_t *out;
|
||||||
uint8_t *buffer=NULL;
|
uint8_t *buffer=NULL;
|
||||||
@@ -1600,7 +1601,7 @@ int CU_handle_UE_CONTEXT_MODIFICATION_RESPONSE(instance_t instance,
|
|||||||
F1AP_UEContextModificationResponseIEs_t *ie;
|
F1AP_UEContextModificationResponseIEs_t *ie;
|
||||||
DevAssert(pdu);
|
DevAssert(pdu);
|
||||||
msg_p = itti_alloc_new_message(TASK_DU_F1, 0, F1AP_UE_CONTEXT_MODIFICATION_RESP);
|
msg_p = itti_alloc_new_message(TASK_DU_F1, 0, F1AP_UE_CONTEXT_MODIFICATION_RESP);
|
||||||
f1ap_ue_context_setup_t *f1ap_ue_context_modification_resp = &F1AP_UE_CONTEXT_MODIFICATION_RESP(msg_p);
|
f1ap_ue_context_modif_resp_t *f1ap_ue_context_modification_resp = &F1AP_UE_CONTEXT_MODIFICATION_RESP(msg_p);
|
||||||
container = &pdu->choice.successfulOutcome->value.choice.UEContextModificationResponse;
|
container = &pdu->choice.successfulOutcome->value.choice.UEContextModificationResponse;
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
@@ -1609,7 +1610,7 @@ int CU_handle_UE_CONTEXT_MODIFICATION_RESPONSE(instance_t instance,
|
|||||||
F1AP_ProtocolIE_ID_id_gNB_CU_UE_F1AP_ID, true);
|
F1AP_ProtocolIE_ID_id_gNB_CU_UE_F1AP_ID, true);
|
||||||
f1ap_ue_context_modification_resp->gNB_CU_ue_id = ie->value.choice.GNB_CU_UE_F1AP_ID;
|
f1ap_ue_context_modification_resp->gNB_CU_ue_id = ie->value.choice.GNB_CU_UE_F1AP_ID;
|
||||||
|
|
||||||
LOG_D(F1AP, "f1ap_ue_context_setup_resp->gNB_CU_ue_id is: %d \n", f1ap_ue_context_modification_resp->gNB_CU_ue_id);
|
LOG_D(F1AP, "f1ap_ue_context_modif_resp->gNB_CU_ue_id is: %d \n", f1ap_ue_context_modification_resp->gNB_CU_ue_id);
|
||||||
|
|
||||||
/* GNB_DU_UE_F1AP_ID */
|
/* GNB_DU_UE_F1AP_ID */
|
||||||
F1AP_FIND_PROTOCOLIE_BY_ID(F1AP_UEContextModificationResponseIEs_t, ie, container,
|
F1AP_FIND_PROTOCOLIE_BY_ID(F1AP_UEContextModificationResponseIEs_t, ie, container,
|
||||||
|
|||||||
@@ -72,8 +72,7 @@ int CU_handle_UE_CONTEXT_RELEASE_COMPLETE(instance_t instance,
|
|||||||
/*
|
/*
|
||||||
* UE Context Modification (gNB-CU initiated)
|
* UE Context Modification (gNB-CU initiated)
|
||||||
*/
|
*/
|
||||||
int CU_send_UE_CONTEXT_MODIFICATION_REQUEST(instance_t instance,
|
int CU_send_UE_CONTEXT_MODIFICATION_REQUEST(instance_t instance, f1ap_ue_context_modif_req_t *f1ap_ue_context_modification_req);
|
||||||
f1ap_ue_context_setup_t *f1ap_ue_context_modification_req);
|
|
||||||
int CU_handle_UE_CONTEXT_MODIFICATION_RESPONSE(instance_t instance,
|
int CU_handle_UE_CONTEXT_MODIFICATION_RESPONSE(instance_t instance,
|
||||||
uint32_t assoc_id,
|
uint32_t assoc_id,
|
||||||
uint32_t stream,
|
uint32_t stream,
|
||||||
|
|||||||
@@ -37,29 +37,24 @@
|
|||||||
#include "f1ap_du_ue_context_management.h"
|
#include "f1ap_du_ue_context_management.h"
|
||||||
#include "openair2/LAYER2/NR_MAC_gNB/mac_rrc_dl_handler.h"
|
#include "openair2/LAYER2/NR_MAC_gNB/mac_rrc_dl_handler.h"
|
||||||
|
|
||||||
#include "rrc_extern.h"
|
|
||||||
#include "openair2/RRC/NR/rrc_gNB_UE_context.h"
|
|
||||||
#include "openair2/LAYER2/NR_MAC_gNB/nr_mac_gNB.h"
|
#include "openair2/LAYER2/NR_MAC_gNB/nr_mac_gNB.h"
|
||||||
#include <openair3/ocp-gtpu/gtp_itf.h>
|
#include <openair3/ocp-gtpu/gtp_itf.h>
|
||||||
|
|
||||||
bool lteDURecvCb(protocol_ctxt_t *ctxt_pP,
|
bool DURecvCb(protocol_ctxt_t *ctxt_pP,
|
||||||
const srb_flag_t srb_flagP,
|
const srb_flag_t srb_flagP,
|
||||||
const rb_id_t rb_idP,
|
const rb_id_t rb_idP,
|
||||||
const mui_t muiP,
|
const mui_t muiP,
|
||||||
const confirm_t confirmP,
|
const confirm_t confirmP,
|
||||||
const sdu_size_t sdu_buffer_sizeP,
|
const sdu_size_t sdu_buffer_sizeP,
|
||||||
unsigned char *const sdu_buffer_pP,
|
unsigned char *const sdu_buffer_pP,
|
||||||
const pdcp_transmission_mode_t modeP,
|
const pdcp_transmission_mode_t modeP,
|
||||||
const uint32_t *sourceL2Id,
|
const uint32_t *sourceL2Id,
|
||||||
const uint32_t *destinationL2Id) {
|
const uint32_t *destinationL2Id)
|
||||||
|
{
|
||||||
// The buffer comes from the stack in gtp-u thread, we have a make a separate buffer to enqueue in a inter-thread message queue
|
// The buffer comes from the stack in gtp-u thread, we have a make a separate buffer to enqueue in a inter-thread message queue
|
||||||
mem_block_t *sdu=get_free_mem_block(sdu_buffer_sizeP, __func__);
|
mem_block_t *sdu=get_free_mem_block(sdu_buffer_sizeP, __func__);
|
||||||
memcpy(sdu->data, sdu_buffer_pP, sdu_buffer_sizeP);
|
memcpy(sdu->data, sdu_buffer_pP, sdu_buffer_sizeP);
|
||||||
// weird rb id management in 4G, not fully understand (looks bad design)
|
du_rlc_data_req(ctxt_pP, srb_flagP, false, rb_idP, muiP, confirmP, sdu_buffer_sizeP, sdu);
|
||||||
// overcomplex: if i understand, on the interface DRB start at 4 because there can be SRB 0..3
|
|
||||||
// but it would be much simpler to use absolute numbering
|
|
||||||
// instead of this "srb flag" associated to these +/-4
|
|
||||||
du_rlc_data_req(ctxt_pP,srb_flagP, false, rb_idP-4,muiP, confirmP, sdu_buffer_sizeP, sdu);
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -138,7 +133,7 @@ int DU_handle_UE_CONTEXT_SETUP_REQUEST(instance_t instance,
|
|||||||
f1ap_ue_context_setup_req->cu_to_du_rrc_information->uE_CapabilityRAT_ContainerList = (uint8_t *)calloc(1,ieCuRrcInfo->value.choice.CUtoDURRCInformation.uE_CapabilityRAT_ContainerList->size);
|
f1ap_ue_context_setup_req->cu_to_du_rrc_information->uE_CapabilityRAT_ContainerList = (uint8_t *)calloc(1,ieCuRrcInfo->value.choice.CUtoDURRCInformation.uE_CapabilityRAT_ContainerList->size);
|
||||||
memcpy(f1ap_ue_context_setup_req->cu_to_du_rrc_information->uE_CapabilityRAT_ContainerList, ieCuRrcInfo->value.choice.CUtoDURRCInformation.uE_CapabilityRAT_ContainerList->buf, ieCuRrcInfo->value.choice.CUtoDURRCInformation.uE_CapabilityRAT_ContainerList->size);
|
memcpy(f1ap_ue_context_setup_req->cu_to_du_rrc_information->uE_CapabilityRAT_ContainerList, ieCuRrcInfo->value.choice.CUtoDURRCInformation.uE_CapabilityRAT_ContainerList->buf, ieCuRrcInfo->value.choice.CUtoDURRCInformation.uE_CapabilityRAT_ContainerList->size);
|
||||||
f1ap_ue_context_setup_req->cu_to_du_rrc_information->uE_CapabilityRAT_ContainerList_length = ieCuRrcInfo->value.choice.CUtoDURRCInformation.uE_CapabilityRAT_ContainerList->size;
|
f1ap_ue_context_setup_req->cu_to_du_rrc_information->uE_CapabilityRAT_ContainerList_length = ieCuRrcInfo->value.choice.CUtoDURRCInformation.uE_CapabilityRAT_ContainerList->size;
|
||||||
LOG_I(F1AP, "Size f1ap_ue_context_setup_req->cu_to_du_rrc_information->uE_CapabilityRAT_ContainerList_length: %d \n", f1ap_ue_context_setup_req->cu_to_du_rrc_information->uE_CapabilityRAT_ContainerList_length);
|
LOG_D(F1AP, "Size f1ap_ue_context_setup_req->cu_to_du_rrc_information->uE_CapabilityRAT_ContainerList_length: %d \n", f1ap_ue_context_setup_req->cu_to_du_rrc_information->uE_CapabilityRAT_ContainerList_length);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -810,17 +805,12 @@ static instance_t du_create_gtpu_instance_to_cu(char *CUaddr, uint16_t CUport, c
|
|||||||
return gtpv1Init(tmp);
|
return gtpv1Init(tmp);
|
||||||
}
|
}
|
||||||
|
|
||||||
int DU_handle_UE_CONTEXT_MODIFICATION_REQUEST(instance_t instance,
|
int DU_handle_UE_CONTEXT_MODIFICATION_REQUEST(instance_t instance, uint32_t assoc_id, uint32_t stream, F1AP_F1AP_PDU_t *pdu)
|
||||||
uint32_t assoc_id,
|
{
|
||||||
uint32_t stream,
|
|
||||||
F1AP_F1AP_PDU_t *pdu) {
|
|
||||||
|
|
||||||
MessageDef *msg_p; // message to RRC
|
|
||||||
F1AP_UEContextModificationRequest_t *container;
|
F1AP_UEContextModificationRequest_t *container;
|
||||||
int i;
|
int i;
|
||||||
DevAssert(pdu);
|
f1ap_ue_context_modif_req_t ue_context_modification = {0};
|
||||||
msg_p = itti_alloc_new_message(TASK_DU_F1, 0, F1AP_UE_CONTEXT_MODIFICATION_REQ);
|
f1ap_ue_context_modif_req_t *f1ap_ue_context_modification_req = &ue_context_modification;
|
||||||
f1ap_ue_context_setup_t *f1ap_ue_context_modification_req = &F1AP_UE_CONTEXT_MODIFICATION_REQ(msg_p);
|
|
||||||
container = &pdu->choice.initiatingMessage->value.choice.UEContextModificationRequest;
|
container = &pdu->choice.initiatingMessage->value.choice.UEContextModificationRequest;
|
||||||
|
|
||||||
/* mandatory */
|
/* mandatory */
|
||||||
@@ -841,7 +831,7 @@ int DU_handle_UE_CONTEXT_MODIFICATION_REQUEST(instance_t instance,
|
|||||||
if(f1ap_ue_context_modification_req->rnti<0)
|
if(f1ap_ue_context_modification_req->rnti<0)
|
||||||
LOG_E(F1AP, "Could not retrieve UE rnti based on the DU UE id \n");
|
LOG_E(F1AP, "Could not retrieve UE rnti based on the DU UE id \n");
|
||||||
else
|
else
|
||||||
LOG_I(F1AP, "Retrieved rnti is: %d \n", f1ap_ue_context_modification_req->rnti);
|
LOG_D(F1AP, "Retrieved rnti is: %d \n", f1ap_ue_context_modification_req->rnti);
|
||||||
|
|
||||||
/* SRB */
|
/* SRB */
|
||||||
F1AP_UEContextModificationRequestIEs_t *ieSrb;
|
F1AP_UEContextModificationRequestIEs_t *ieSrb;
|
||||||
@@ -967,15 +957,16 @@ int DU_handle_UE_CONTEXT_MODIFICATION_REQUEST(instance_t instance,
|
|||||||
LOG_E(F1AP, " RRCContainer in UEContextModificationRequestIEs size id 0\n");
|
LOG_E(F1AP, " RRCContainer in UEContextModificationRequestIEs size id 0\n");
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
LOG_W(F1AP, "can't find RRCContainer in UEContextModificationRequestIEs by id %ld \n", F1AP_ProtocolIE_ID_id_RRCContainer);
|
LOG_D(F1AP, "can't find RRCContainer in UEContextModificationRequestIEs by id %ld \n", F1AP_ProtocolIE_ID_id_RRCContainer);
|
||||||
}
|
}
|
||||||
|
|
||||||
itti_send_msg_to_task(TASK_RRC_GNB, instance, msg_p);
|
ue_context_modification_request(f1ap_ue_context_modification_req);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
//void DU_send_UE_CONTEXT_MODIFICATION_RESPONSE(F1AP_UEContextModificationResponse_t *UEContextModificationResponse) {
|
//void DU_send_UE_CONTEXT_MODIFICATION_RESPONSE(F1AP_UEContextModificationResponse_t *UEContextModificationResponse) {
|
||||||
int DU_send_UE_CONTEXT_MODIFICATION_RESPONSE(instance_t instance, f1ap_ue_context_setup_t *resp) {
|
int DU_send_UE_CONTEXT_MODIFICATION_RESPONSE(instance_t instance, f1ap_ue_context_modif_resp_t *resp)
|
||||||
|
{
|
||||||
F1AP_F1AP_PDU_t pdu= {0};
|
F1AP_F1AP_PDU_t pdu= {0};
|
||||||
F1AP_UEContextModificationResponse_t *out;
|
F1AP_UEContextModificationResponse_t *out;
|
||||||
uint8_t *buffer=NULL;
|
uint8_t *buffer=NULL;
|
||||||
@@ -1062,6 +1053,21 @@ int DU_send_UE_CONTEXT_MODIFICATION_RESPONSE(instance_t instance, f1ap_ue_contex
|
|||||||
drbs_setupmod_item->dRBID = resp->drbs_to_be_setup[i].drb_id;
|
drbs_setupmod_item->dRBID = resp->drbs_to_be_setup[i].drb_id;
|
||||||
|
|
||||||
for (int j=0; j<resp->drbs_to_be_setup[i].up_dl_tnl_length; j++) {
|
for (int j=0; j<resp->drbs_to_be_setup[i].up_dl_tnl_length; j++) {
|
||||||
|
f1ap_drb_to_be_setup_t *drb = &resp->drbs_to_be_setup[i];
|
||||||
|
transport_layer_addr_t tl_addr = {0};
|
||||||
|
memcpy(tl_addr.buffer, &drb->up_ul_tnl[0].tl_address, sizeof(drb->up_ul_tnl[0].tl_address));
|
||||||
|
tl_addr.length = sizeof(drb->up_ul_tnl[0].tl_address) * 8;
|
||||||
|
drb->up_dl_tnl[j].teid = newGtpuCreateTunnel(getCxt(false, instance)->gtpInst,
|
||||||
|
resp->rnti,
|
||||||
|
drb->drb_id,
|
||||||
|
drb->drb_id,
|
||||||
|
drb->up_ul_tnl[j].teid,
|
||||||
|
-1, // no qfi
|
||||||
|
tl_addr,
|
||||||
|
drb->up_ul_tnl[0].port,
|
||||||
|
DURecvCb,
|
||||||
|
NULL);
|
||||||
|
|
||||||
/* ADD */
|
/* ADD */
|
||||||
asn1cSequenceAdd(drbs_setupmod_item->dLUPTNLInformation_ToBeSetup_List.list,
|
asn1cSequenceAdd(drbs_setupmod_item->dLUPTNLInformation_ToBeSetup_List.list,
|
||||||
F1AP_DLUPTNLInformation_ToBeSetup_Item_t, dLUPTNLInformation_ToBeSetup_Item);
|
F1AP_DLUPTNLInformation_ToBeSetup_Item_t, dLUPTNLInformation_ToBeSetup_Item);
|
||||||
|
|||||||
@@ -72,7 +72,7 @@ int DU_handle_UE_CONTEXT_MODIFICATION_REQUEST(instance_t instance,
|
|||||||
uint32_t assoc_id,
|
uint32_t assoc_id,
|
||||||
uint32_t stream,
|
uint32_t stream,
|
||||||
F1AP_F1AP_PDU_t *pdu);
|
F1AP_F1AP_PDU_t *pdu);
|
||||||
int DU_send_UE_CONTEXT_MODIFICATION_RESPONSE(instance_t instance, f1ap_ue_context_setup_t *resp);
|
int DU_send_UE_CONTEXT_MODIFICATION_RESPONSE(instance_t instance, f1ap_ue_context_modif_resp_t *resp);
|
||||||
int DU_send_UE_CONTEXT_MODIFICATION_FAILURE(instance_t instance);
|
int DU_send_UE_CONTEXT_MODIFICATION_FAILURE(instance_t instance);
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -44,10 +44,6 @@
|
|||||||
|
|
||||||
#include "openair2/LAYER2/nr_rlc/nr_rlc_oai_api.h"
|
#include "openair2/LAYER2/nr_rlc/nr_rlc_oai_api.h"
|
||||||
|
|
||||||
/* TODO REMOVE_DU_RRC: the RRC in the DU is a hack and should be taken out in the future */
|
|
||||||
#include "RRC/NR/nr_rrc_extern.h"
|
|
||||||
#include "RRC/NR/rrc_gNB_UE_context.h"
|
|
||||||
#include "RRC/L2_INTERFACE/openair_rrc_L2_interface.h"
|
|
||||||
#include "RRC/NR/MESSAGES/asn1_msg.h"
|
#include "RRC/NR/MESSAGES/asn1_msg.h"
|
||||||
|
|
||||||
#include "intertask_interface.h"
|
#include "intertask_interface.h"
|
||||||
@@ -2944,12 +2940,6 @@ void prepare_initial_ul_rrc_message(gNB_MAC_INST *mac, NR_UE_info_t *UE)
|
|||||||
UE->CellGroup = cellGroupConfig;
|
UE->CellGroup = cellGroupConfig;
|
||||||
nr_mac_update_cellgroup(mac, UE->rnti, cellGroupConfig);
|
nr_mac_update_cellgroup(mac, UE->rnti, cellGroupConfig);
|
||||||
|
|
||||||
/* TODO REMOVE_DU_RRC: the RRC in the DU is a hack and should be taken out in the future */
|
|
||||||
if (NODE_IS_DU(rrc->node_type)) {
|
|
||||||
rrc_gNB_ue_context_t *ue = rrc_gNB_create_ue_context(UE->rnti, rrc, UE->rnti);
|
|
||||||
ue->ue_context.masterCellGroup = cellGroupConfig;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* activate SRB0 */
|
/* activate SRB0 */
|
||||||
nr_rlc_activate_srb0(UE->rnti, mac, UE, send_initial_ul_rrc_message);
|
nr_rlc_activate_srb0(UE->rnti, mac, UE, send_initial_ul_rrc_message);
|
||||||
|
|
||||||
|
|||||||
@@ -33,25 +33,27 @@ static NR_RLC_BearerConfig_t *get_bearerconfig_from_srb(const f1ap_srb_to_be_set
|
|||||||
return get_SRB_RLC_BearerConfig(srb->srb_id, priority, bucket);
|
return get_SRB_RLC_BearerConfig(srb->srb_id, priority, bucket);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void handle_ue_context_srbs_setup(const f1ap_ue_context_setup_t *req,
|
static int handle_ue_context_srbs_setup(int rnti,
|
||||||
f1ap_ue_context_setup_t *resp,
|
int srbs_len,
|
||||||
NR_CellGroupConfig_t *cellGroupConfig)
|
const f1ap_srb_to_be_setup_t *req_srbs,
|
||||||
|
f1ap_srb_to_be_setup_t **resp_srbs,
|
||||||
|
NR_CellGroupConfig_t *cellGroupConfig)
|
||||||
{
|
{
|
||||||
DevAssert(req != NULL && resp != NULL && cellGroupConfig != NULL);
|
DevAssert(req_srbs != NULL && resp_srbs != NULL && cellGroupConfig != NULL);
|
||||||
|
|
||||||
resp->srbs_to_be_setup_length = req->srbs_to_be_setup_length;
|
*resp_srbs = calloc(srbs_len, sizeof(**resp_srbs));
|
||||||
resp->srbs_to_be_setup = calloc(req->srbs_to_be_setup_length, sizeof(*resp->srbs_to_be_setup));
|
AssertFatal(*resp_srbs != NULL, "out of memory\n");
|
||||||
AssertFatal(resp->srbs_to_be_setup != NULL, "out of memory\n");
|
for (int i = 0; i < srbs_len; i++) {
|
||||||
for (int i = 0; i < req->srbs_to_be_setup_length; i++) {
|
const f1ap_srb_to_be_setup_t *srb = &req_srbs[i];
|
||||||
f1ap_srb_to_be_setup_t *srb = &req->srbs_to_be_setup[i];
|
|
||||||
NR_RLC_BearerConfig_t *rlc_BearerConfig = get_bearerconfig_from_srb(srb);
|
NR_RLC_BearerConfig_t *rlc_BearerConfig = get_bearerconfig_from_srb(srb);
|
||||||
nr_rlc_add_srb(req->rnti, srb->srb_id, rlc_BearerConfig);
|
nr_rlc_add_srb(rnti, srb->srb_id, rlc_BearerConfig);
|
||||||
|
|
||||||
resp->srbs_to_be_setup[i] = *srb;
|
(*resp_srbs)[i] = *srb;
|
||||||
|
|
||||||
int ret = ASN_SEQUENCE_ADD(&cellGroupConfig->rlc_BearerToAddModList->list, rlc_BearerConfig);
|
int ret = ASN_SEQUENCE_ADD(&cellGroupConfig->rlc_BearerToAddModList->list, rlc_BearerConfig);
|
||||||
DevAssert(ret == 0);
|
DevAssert(ret == 0);
|
||||||
}
|
}
|
||||||
|
return srbs_len;
|
||||||
}
|
}
|
||||||
|
|
||||||
static NR_RLC_BearerConfig_t *get_bearerconfig_from_drb(const f1ap_drb_to_be_setup_t *drb)
|
static NR_RLC_BearerConfig_t *get_bearerconfig_from_drb(const f1ap_drb_to_be_setup_t *drb)
|
||||||
@@ -61,27 +63,31 @@ static NR_RLC_BearerConfig_t *get_bearerconfig_from_drb(const f1ap_drb_to_be_set
|
|||||||
return get_DRB_RLC_BearerConfig(3 + drb->drb_id, drb->drb_id, rlc_conf, priority);
|
return get_DRB_RLC_BearerConfig(3 + drb->drb_id, drb->drb_id, rlc_conf, priority);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void handle_ue_context_drbs_setup(const f1ap_ue_context_setup_t *req,
|
static int handle_ue_context_drbs_setup(int rnti,
|
||||||
f1ap_ue_context_setup_t *resp,
|
int drbs_len,
|
||||||
NR_CellGroupConfig_t *cellGroupConfig)
|
const f1ap_drb_to_be_setup_t *req_drbs,
|
||||||
|
f1ap_drb_to_be_setup_t **resp_drbs,
|
||||||
|
NR_CellGroupConfig_t *cellGroupConfig)
|
||||||
{
|
{
|
||||||
DevAssert(req != NULL && resp != NULL && cellGroupConfig != NULL);
|
DevAssert(req_drbs != NULL && resp_drbs != NULL && cellGroupConfig != NULL);
|
||||||
|
|
||||||
/* Note: the actual GTP tunnels are created in the F1AP breanch of
|
/* Note: the actual GTP tunnels are created in the F1AP breanch of
|
||||||
* ue_context_*_response() */
|
* ue_context_*_response() */
|
||||||
resp->drbs_to_be_setup_length = req->drbs_to_be_setup_length;
|
*resp_drbs = calloc(drbs_len, sizeof(**resp_drbs));
|
||||||
resp->drbs_to_be_setup = calloc(req->drbs_to_be_setup_length, sizeof(*resp->drbs_to_be_setup));
|
AssertFatal(*resp_drbs != NULL, "out of memory\n");
|
||||||
AssertFatal(resp->drbs_to_be_setup != NULL, "out of memory\n");
|
for (int i = 0; i < drbs_len; i++) {
|
||||||
for (int i = 0; i < req->drbs_to_be_setup_length; i++) {
|
const f1ap_drb_to_be_setup_t *drb = &req_drbs[i];
|
||||||
f1ap_drb_to_be_setup_t *drb = &req->drbs_to_be_setup[i];
|
|
||||||
NR_RLC_BearerConfig_t *rlc_BearerConfig = get_bearerconfig_from_drb(drb);
|
NR_RLC_BearerConfig_t *rlc_BearerConfig = get_bearerconfig_from_drb(drb);
|
||||||
nr_rlc_add_drb(req->rnti, drb->drb_id, rlc_BearerConfig);
|
nr_rlc_add_drb(rnti, drb->drb_id, rlc_BearerConfig);
|
||||||
|
|
||||||
resp->drbs_to_be_setup[i] = *drb;
|
(*resp_drbs)[i] = *drb;
|
||||||
|
// just put same number of tunnels in DL as in UL
|
||||||
|
(*resp_drbs)[i].up_dl_tnl_length = drb->up_ul_tnl_length;
|
||||||
|
|
||||||
int ret = ASN_SEQUENCE_ADD(&cellGroupConfig->rlc_BearerToAddModList->list, rlc_BearerConfig);
|
int ret = ASN_SEQUENCE_ADD(&cellGroupConfig->rlc_BearerToAddModList->list, rlc_BearerConfig);
|
||||||
DevAssert(ret == 0);
|
DevAssert(ret == 0);
|
||||||
}
|
}
|
||||||
|
return drbs_len;
|
||||||
}
|
}
|
||||||
|
|
||||||
void ue_context_setup_request(const f1ap_ue_context_setup_t *req)
|
void ue_context_setup_request(const f1ap_ue_context_setup_t *req)
|
||||||
@@ -105,11 +111,20 @@ void ue_context_setup_request(const f1ap_ue_context_setup_t *req)
|
|||||||
NR_UE_info_t *UE = find_nr_UE(&RC.nrmac[0]->UE_info, req->rnti);
|
NR_UE_info_t *UE = find_nr_UE(&RC.nrmac[0]->UE_info, req->rnti);
|
||||||
AssertFatal(UE != NULL, "did not find UE with RNTI %04x, but UE Context Setup Failed not implemented\n", req->rnti);
|
AssertFatal(UE != NULL, "did not find UE with RNTI %04x, but UE Context Setup Failed not implemented\n", req->rnti);
|
||||||
|
|
||||||
if (req->srbs_to_be_setup_length > 0)
|
if (req->srbs_to_be_setup_length > 0) {
|
||||||
handle_ue_context_srbs_setup(req, &resp, UE->CellGroup);
|
resp.srbs_to_be_setup_length = handle_ue_context_srbs_setup(req->rnti,
|
||||||
|
req->srbs_to_be_setup_length,
|
||||||
|
req->srbs_to_be_setup,
|
||||||
|
&resp.srbs_to_be_setup,
|
||||||
|
UE->CellGroup);
|
||||||
|
}
|
||||||
|
|
||||||
if (req->drbs_to_be_setup_length > 0) {
|
if (req->drbs_to_be_setup_length > 0) {
|
||||||
handle_ue_context_drbs_setup(req, &resp, NULL);
|
resp.drbs_to_be_setup_length = handle_ue_context_drbs_setup(req->rnti,
|
||||||
|
req->drbs_to_be_setup_length,
|
||||||
|
req->drbs_to_be_setup,
|
||||||
|
&resp.drbs_to_be_setup,
|
||||||
|
UE->CellGroup);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (req->rrc_container != NULL)
|
if (req->rrc_container != NULL)
|
||||||
@@ -147,6 +162,85 @@ void ue_context_setup_request(const f1ap_ue_context_setup_t *req)
|
|||||||
free(resp.du_to_cu_rrc_information);
|
free(resp.du_to_cu_rrc_information);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void ue_context_modification_request(const f1ap_ue_context_modif_req_t *req)
|
||||||
|
{
|
||||||
|
gNB_MAC_INST *mac = RC.nrmac[0];
|
||||||
|
f1ap_ue_context_modif_resp_t resp = {
|
||||||
|
.gNB_CU_ue_id = req->gNB_CU_ue_id,
|
||||||
|
.gNB_DU_ue_id = req->gNB_DU_ue_id,
|
||||||
|
.rnti = req->rnti,
|
||||||
|
};
|
||||||
|
|
||||||
|
if (req->cu_to_du_rrc_information != NULL) {
|
||||||
|
AssertFatal(req->cu_to_du_rrc_information->cG_ConfigInfo == NULL, "CG-ConfigInfo not handled\n");
|
||||||
|
AssertFatal(req->cu_to_du_rrc_information->uE_CapabilityRAT_ContainerList == NULL, "UE capabilities not handled yet\n");
|
||||||
|
AssertFatal(req->cu_to_du_rrc_information->measConfig == NULL, "MeasConfig not handled\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
NR_SCHED_LOCK(&mac->sched_lock);
|
||||||
|
NR_UE_info_t *UE = find_nr_UE(&RC.nrmac[0]->UE_info, req->rnti);
|
||||||
|
|
||||||
|
if (req->srbs_to_be_setup_length > 0) {
|
||||||
|
resp.srbs_to_be_setup_length = handle_ue_context_srbs_setup(req->rnti,
|
||||||
|
req->srbs_to_be_setup_length,
|
||||||
|
req->srbs_to_be_setup,
|
||||||
|
&resp.srbs_to_be_setup,
|
||||||
|
UE->CellGroup);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (req->drbs_to_be_setup_length > 0) {
|
||||||
|
resp.drbs_to_be_setup_length = handle_ue_context_drbs_setup(req->rnti,
|
||||||
|
req->drbs_to_be_setup_length,
|
||||||
|
req->drbs_to_be_setup,
|
||||||
|
&resp.drbs_to_be_setup,
|
||||||
|
UE->CellGroup);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (req->rrc_container != NULL)
|
||||||
|
nr_rlc_srb_recv_sdu(req->rnti, DCCH, req->rrc_container, req->rrc_container_length);
|
||||||
|
|
||||||
|
if (req->ReconfigComplOutcome != RRCreconf_info_not_present && req->ReconfigComplOutcome != RRCreconf_success) {
|
||||||
|
LOG_E(NR_MAC,
|
||||||
|
"RRC reconfiguration outcome unsuccessful, but no rollback mechanism implemented to come back to old configuration\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
if (req->srbs_to_be_setup_length > 0 || req->drbs_to_be_setup_length > 0) {
|
||||||
|
/* TODO: if we change e.g. BWP or MCS table, need to automatically call
|
||||||
|
* configure_UE_BWP() (form nr_mac_update_timers()) after some time? */
|
||||||
|
|
||||||
|
resp.du_to_cu_rrc_information = calloc(1, sizeof(du_to_cu_rrc_information_t));
|
||||||
|
AssertFatal(resp.du_to_cu_rrc_information != NULL, "out of memory\n");
|
||||||
|
resp.du_to_cu_rrc_information->cellGroupConfig = calloc(1, 1024);
|
||||||
|
AssertFatal(resp.du_to_cu_rrc_information->cellGroupConfig != NULL, "out of memory\n");
|
||||||
|
asn_enc_rval_t enc_rval = uper_encode_to_buffer(&asn_DEF_NR_CellGroupConfig,
|
||||||
|
NULL,
|
||||||
|
UE->CellGroup,
|
||||||
|
resp.du_to_cu_rrc_information->cellGroupConfig,
|
||||||
|
1024);
|
||||||
|
AssertFatal(enc_rval.encoded > 0, "Could not encode CellGroup, failed element %s\n", enc_rval.failed_type->name);
|
||||||
|
resp.du_to_cu_rrc_information->cellGroupConfig_length = (enc_rval.encoded + 7) >> 3;
|
||||||
|
|
||||||
|
/* works? */
|
||||||
|
nr_mac_update_cellgroup(RC.nrmac[0], req->rnti, UE->CellGroup);
|
||||||
|
}
|
||||||
|
NR_SCHED_UNLOCK(&mac->sched_lock);
|
||||||
|
|
||||||
|
/* some sanity checks, since we use the same type for request and response */
|
||||||
|
DevAssert(resp.cu_to_du_rrc_information == NULL);
|
||||||
|
// resp.du_to_cu_rrc_information can be either NULL or not
|
||||||
|
DevAssert(resp.rrc_container == NULL && resp.rrc_container_length == 0);
|
||||||
|
|
||||||
|
mac->mac_rrc.ue_context_modification_response(req, &resp);
|
||||||
|
|
||||||
|
/* free the memory we allocated above */
|
||||||
|
free(resp.srbs_to_be_setup);
|
||||||
|
free(resp.drbs_to_be_setup);
|
||||||
|
if (resp.du_to_cu_rrc_information != NULL) {
|
||||||
|
free(resp.du_to_cu_rrc_information->cellGroupConfig);
|
||||||
|
free(resp.du_to_cu_rrc_information);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void ue_context_release_command(const f1ap_ue_context_release_cmd_t *cmd)
|
void ue_context_release_command(const f1ap_ue_context_release_cmd_t *cmd)
|
||||||
{
|
{
|
||||||
/* mark UE as to be deleted after PUSCH failure */
|
/* mark UE as to be deleted after PUSCH failure */
|
||||||
|
|||||||
@@ -26,6 +26,7 @@
|
|||||||
#include "f1ap_messages_types.h"
|
#include "f1ap_messages_types.h"
|
||||||
|
|
||||||
void ue_context_setup_request(const f1ap_ue_context_setup_t *req);
|
void ue_context_setup_request(const f1ap_ue_context_setup_t *req);
|
||||||
|
void ue_context_modification_request(const f1ap_ue_context_modif_req_t *req);
|
||||||
void ue_context_release_command(const f1ap_ue_context_release_cmd_t *cmd);
|
void ue_context_release_command(const f1ap_ue_context_release_cmd_t *cmd);
|
||||||
|
|
||||||
int dl_rrc_message(module_id_t module_id, const f1ap_dl_rrc_message_t *dl_rrc);
|
int dl_rrc_message(module_id_t module_id, const f1ap_dl_rrc_message_t *dl_rrc);
|
||||||
|
|||||||
@@ -26,6 +26,8 @@
|
|||||||
#include "f1ap_messages_types.h"
|
#include "f1ap_messages_types.h"
|
||||||
|
|
||||||
typedef void (*ue_context_setup_response_func_t)(const f1ap_ue_context_setup_t* req, const f1ap_ue_context_setup_t *resp);
|
typedef void (*ue_context_setup_response_func_t)(const f1ap_ue_context_setup_t* req, const f1ap_ue_context_setup_t *resp);
|
||||||
|
typedef void (*ue_context_modification_response_func_t)(const f1ap_ue_context_modif_req_t *req,
|
||||||
|
const f1ap_ue_context_modif_resp_t *resp);
|
||||||
typedef void (*ue_context_release_request_func_t)(const f1ap_ue_context_release_req_t* req);
|
typedef void (*ue_context_release_request_func_t)(const f1ap_ue_context_release_req_t* req);
|
||||||
typedef void (*ue_context_release_complete_func_t)(const f1ap_ue_context_release_complete_t *complete);
|
typedef void (*ue_context_release_complete_func_t)(const f1ap_ue_context_release_complete_t *complete);
|
||||||
|
|
||||||
|
|||||||
@@ -55,6 +55,63 @@ static void ue_context_setup_response_direct(const f1ap_ue_context_setup_t *req,
|
|||||||
itti_send_msg_to_task(TASK_RRC_GNB, 0, msg);
|
itti_send_msg_to_task(TASK_RRC_GNB, 0, msg);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void ue_context_modification_response_direct(const f1ap_ue_context_modif_req_t *req,
|
||||||
|
const f1ap_ue_context_modif_resp_t *resp)
|
||||||
|
{
|
||||||
|
(void)req; /* we don't need the request -- it is to set up GTP in F1 case */
|
||||||
|
MessageDef *msg = itti_alloc_new_message(TASK_MAC_GNB, 0, F1AP_UE_CONTEXT_MODIFICATION_RESP);
|
||||||
|
f1ap_ue_context_modif_resp_t *f1ap_msg = &F1AP_UE_CONTEXT_MODIFICATION_RESP(msg);
|
||||||
|
|
||||||
|
f1ap_msg->gNB_CU_ue_id = resp->gNB_CU_ue_id;
|
||||||
|
f1ap_msg->gNB_DU_ue_id = resp->gNB_DU_ue_id;
|
||||||
|
f1ap_msg->rnti = resp->rnti;
|
||||||
|
f1ap_msg->mcc = resp->mcc;
|
||||||
|
f1ap_msg->mnc = resp->mnc;
|
||||||
|
f1ap_msg->mnc_digit_length = resp->mnc_digit_length;
|
||||||
|
f1ap_msg->nr_cellid = resp->nr_cellid;
|
||||||
|
f1ap_msg->servCellIndex = resp->servCellIndex;
|
||||||
|
AssertFatal(resp->cellULConfigured == NULL, "not handled\n");
|
||||||
|
f1ap_msg->servCellId = resp->servCellId;
|
||||||
|
|
||||||
|
DevAssert(resp->cu_to_du_rrc_information == NULL && resp->cu_to_du_rrc_information_length == 0);
|
||||||
|
if (resp->du_to_cu_rrc_information) {
|
||||||
|
f1ap_msg->du_to_cu_rrc_information = malloc(sizeof(*resp->du_to_cu_rrc_information));
|
||||||
|
AssertFatal(f1ap_msg->du_to_cu_rrc_information != NULL, "out of memory\n");
|
||||||
|
f1ap_msg->du_to_cu_rrc_information_length = resp->du_to_cu_rrc_information_length;
|
||||||
|
du_to_cu_rrc_information_t *du2cu = f1ap_msg->du_to_cu_rrc_information;
|
||||||
|
du2cu->cellGroupConfig_length = resp->du_to_cu_rrc_information->cellGroupConfig_length;
|
||||||
|
du2cu->cellGroupConfig = calloc(du2cu->cellGroupConfig_length, sizeof(*du2cu->cellGroupConfig));
|
||||||
|
AssertFatal(du2cu->cellGroupConfig != NULL, "out of memory\n");
|
||||||
|
memcpy(du2cu->cellGroupConfig, resp->du_to_cu_rrc_information->cellGroupConfig, du2cu->cellGroupConfig_length);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (resp->drbs_to_be_setup_length > 0) {
|
||||||
|
DevAssert(resp->drbs_to_be_setup != NULL);
|
||||||
|
f1ap_msg->drbs_to_be_setup_length = resp->drbs_to_be_setup_length;
|
||||||
|
f1ap_msg->drbs_to_be_setup = calloc(f1ap_msg->drbs_to_be_setup_length, sizeof(*f1ap_msg->drbs_to_be_setup));
|
||||||
|
for (int i = 0; i < f1ap_msg->drbs_to_be_setup_length; ++i)
|
||||||
|
f1ap_msg->drbs_to_be_setup[i] = resp->drbs_to_be_setup[i];
|
||||||
|
}
|
||||||
|
|
||||||
|
DevAssert(resp->drbs_to_be_modified == NULL && resp->drbs_to_be_modified_length == 0);
|
||||||
|
f1ap_msg->QoS_information_type = resp->QoS_information_type;
|
||||||
|
AssertFatal(resp->drbs_failed_to_be_setup_length == 0 && resp->drbs_failed_to_be_setup == NULL, "not implemented yet\n");
|
||||||
|
|
||||||
|
if (resp->srbs_to_be_setup_length > 0) {
|
||||||
|
DevAssert(resp->srbs_to_be_setup != NULL);
|
||||||
|
f1ap_msg->srbs_to_be_setup_length = resp->srbs_to_be_setup_length;
|
||||||
|
f1ap_msg->srbs_to_be_setup = calloc(f1ap_msg->srbs_to_be_setup_length, sizeof(*f1ap_msg->srbs_to_be_setup));
|
||||||
|
for (int i = 0; i < f1ap_msg->srbs_to_be_setup_length; ++i)
|
||||||
|
f1ap_msg->srbs_to_be_setup[i] = resp->srbs_to_be_setup[i];
|
||||||
|
}
|
||||||
|
|
||||||
|
AssertFatal(resp->srbs_failed_to_be_setup_length == 0 && resp->srbs_failed_to_be_setup == NULL, "not implemented yet\n");
|
||||||
|
|
||||||
|
DevAssert(resp->rrc_container == NULL && resp->rrc_container_length == 0);
|
||||||
|
|
||||||
|
itti_send_msg_to_task(TASK_RRC_GNB, 0, msg);
|
||||||
|
}
|
||||||
|
|
||||||
static void ue_context_release_request_direct(const f1ap_ue_context_release_req_t* req)
|
static void ue_context_release_request_direct(const f1ap_ue_context_release_req_t* req)
|
||||||
{
|
{
|
||||||
MessageDef *msg = itti_alloc_new_message(TASK_MAC_GNB, 0, F1AP_UE_CONTEXT_RELEASE_REQ);
|
MessageDef *msg = itti_alloc_new_message(TASK_MAC_GNB, 0, F1AP_UE_CONTEXT_RELEASE_REQ);
|
||||||
@@ -94,6 +151,7 @@ static void initial_ul_rrc_message_transfer_direct(module_id_t module_id, const
|
|||||||
void mac_rrc_ul_direct_init(struct nr_mac_rrc_ul_if_s *mac_rrc)
|
void mac_rrc_ul_direct_init(struct nr_mac_rrc_ul_if_s *mac_rrc)
|
||||||
{
|
{
|
||||||
mac_rrc->ue_context_setup_response = ue_context_setup_response_direct;
|
mac_rrc->ue_context_setup_response = ue_context_setup_response_direct;
|
||||||
|
mac_rrc->ue_context_modification_response = ue_context_modification_response_direct;
|
||||||
mac_rrc->ue_context_release_request = ue_context_release_request_direct;
|
mac_rrc->ue_context_release_request = ue_context_release_request_direct;
|
||||||
mac_rrc->ue_context_release_complete = ue_context_release_complete_direct;
|
mac_rrc->ue_context_release_complete = ue_context_release_complete_direct;
|
||||||
mac_rrc->initial_ul_rrc_message_transfer = initial_ul_rrc_message_transfer_direct;
|
mac_rrc->initial_ul_rrc_message_transfer = initial_ul_rrc_message_transfer_direct;
|
||||||
|
|||||||
@@ -60,6 +60,42 @@ static void ue_context_setup_response_f1ap(const f1ap_ue_context_setup_t *req, c
|
|||||||
itti_send_msg_to_task(TASK_DU_F1, 0, msg);
|
itti_send_msg_to_task(TASK_DU_F1, 0, msg);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void ue_context_modification_response_f1ap(const f1ap_ue_context_modif_req_t *req, const f1ap_ue_context_modif_resp_t *resp)
|
||||||
|
{
|
||||||
|
MessageDef *msg = itti_alloc_new_message(TASK_MAC_GNB, 0, F1AP_UE_CONTEXT_MODIFICATION_RESP);
|
||||||
|
f1ap_ue_context_modif_resp_t *f1ap_msg = &F1AP_UE_CONTEXT_MODIFICATION_RESP(msg);
|
||||||
|
/* copy all fields, but reallocate rrc_containers! */
|
||||||
|
*f1ap_msg = *resp;
|
||||||
|
|
||||||
|
if (resp->srbs_to_be_setup_length > 0) {
|
||||||
|
DevAssert(resp->srbs_to_be_setup != NULL);
|
||||||
|
f1ap_msg->srbs_to_be_setup_length = resp->srbs_to_be_setup_length;
|
||||||
|
f1ap_msg->srbs_to_be_setup = calloc(f1ap_msg->srbs_to_be_setup_length, sizeof(*f1ap_msg->srbs_to_be_setup));
|
||||||
|
for (int i = 0; i < f1ap_msg->srbs_to_be_setup_length; ++i)
|
||||||
|
f1ap_msg->srbs_to_be_setup[i] = resp->srbs_to_be_setup[i];
|
||||||
|
}
|
||||||
|
if (resp->drbs_to_be_setup_length > 0) {
|
||||||
|
DevAssert(resp->drbs_to_be_setup != NULL);
|
||||||
|
f1ap_msg->drbs_to_be_setup_length = resp->drbs_to_be_setup_length;
|
||||||
|
f1ap_msg->drbs_to_be_setup = calloc(f1ap_msg->drbs_to_be_setup_length, sizeof(*f1ap_msg->drbs_to_be_setup));
|
||||||
|
for (int i = 0; i < f1ap_msg->drbs_to_be_setup_length; ++i)
|
||||||
|
f1ap_msg->drbs_to_be_setup[i] = resp->drbs_to_be_setup[i];
|
||||||
|
}
|
||||||
|
|
||||||
|
if (resp->du_to_cu_rrc_information != NULL) {
|
||||||
|
f1ap_msg->du_to_cu_rrc_information = calloc(1, sizeof(*resp->du_to_cu_rrc_information));
|
||||||
|
AssertFatal(f1ap_msg->du_to_cu_rrc_information != NULL, "out of memory\n");
|
||||||
|
f1ap_msg->du_to_cu_rrc_information_length = resp->du_to_cu_rrc_information_length;
|
||||||
|
du_to_cu_rrc_information_t *du2cu = f1ap_msg->du_to_cu_rrc_information;
|
||||||
|
du2cu->cellGroupConfig_length = resp->du_to_cu_rrc_information->cellGroupConfig_length;
|
||||||
|
du2cu->cellGroupConfig = calloc(du2cu->cellGroupConfig_length, sizeof(*du2cu->cellGroupConfig));
|
||||||
|
AssertFatal(du2cu->cellGroupConfig != NULL, "out of memory\n");
|
||||||
|
memcpy(du2cu->cellGroupConfig, resp->du_to_cu_rrc_information->cellGroupConfig, du2cu->cellGroupConfig_length);
|
||||||
|
}
|
||||||
|
|
||||||
|
itti_send_msg_to_task(TASK_DU_F1, 0, msg);
|
||||||
|
}
|
||||||
|
|
||||||
static void ue_context_release_request_f1ap(const f1ap_ue_context_release_req_t* req)
|
static void ue_context_release_request_f1ap(const f1ap_ue_context_release_req_t* req)
|
||||||
{
|
{
|
||||||
MessageDef *msg = itti_alloc_new_message(TASK_MAC_GNB, 0, F1AP_UE_CONTEXT_RELEASE_REQ);
|
MessageDef *msg = itti_alloc_new_message(TASK_MAC_GNB, 0, F1AP_UE_CONTEXT_RELEASE_REQ);
|
||||||
@@ -101,6 +137,7 @@ static void initial_ul_rrc_message_transfer_f1ap(module_id_t module_id, const f1
|
|||||||
void mac_rrc_ul_f1ap_init(struct nr_mac_rrc_ul_if_s *mac_rrc)
|
void mac_rrc_ul_f1ap_init(struct nr_mac_rrc_ul_if_s *mac_rrc)
|
||||||
{
|
{
|
||||||
mac_rrc->ue_context_setup_response = ue_context_setup_response_f1ap;
|
mac_rrc->ue_context_setup_response = ue_context_setup_response_f1ap;
|
||||||
|
mac_rrc->ue_context_modification_response = ue_context_modification_response_f1ap;
|
||||||
mac_rrc->ue_context_release_request = ue_context_release_request_f1ap;
|
mac_rrc->ue_context_release_request = ue_context_release_request_f1ap;
|
||||||
mac_rrc->ue_context_release_complete = ue_context_release_complete_f1ap;
|
mac_rrc->ue_context_release_complete = ue_context_release_complete_f1ap;
|
||||||
mac_rrc->initial_ul_rrc_message_transfer = initial_ul_rrc_message_transfer_f1ap;
|
mac_rrc->initial_ul_rrc_message_transfer = initial_ul_rrc_message_transfer_f1ap;
|
||||||
|
|||||||
@@ -662,6 +662,7 @@ typedef struct NR_bler_options {
|
|||||||
|
|
||||||
typedef struct nr_mac_rrc_ul_if_s {
|
typedef struct nr_mac_rrc_ul_if_s {
|
||||||
ue_context_setup_response_func_t ue_context_setup_response;
|
ue_context_setup_response_func_t ue_context_setup_response;
|
||||||
|
ue_context_modification_response_func_t ue_context_modification_response;
|
||||||
ue_context_release_request_func_t ue_context_release_request;
|
ue_context_release_request_func_t ue_context_release_request;
|
||||||
ue_context_release_complete_func_t ue_context_release_complete;
|
ue_context_release_complete_func_t ue_context_release_complete;
|
||||||
initial_ul_rrc_message_transfer_func_t initial_ul_rrc_message_transfer;
|
initial_ul_rrc_message_transfer_func_t initial_ul_rrc_message_transfer;
|
||||||
|
|||||||
@@ -190,6 +190,19 @@ static void cucp_cuup_bearer_context_setup_direct(e1ap_bearer_setup_req_t *const
|
|||||||
PROTOCOL_CTXT_SET_BY_MODULE_ID(&ctxt, 0, GNB_FLAG_YES, UE->rnti, 0, 0, 0);
|
PROTOCOL_CTXT_SET_BY_MODULE_ID(&ctxt, 0, GNB_FLAG_YES, UE->rnti, 0, 0, 0);
|
||||||
|
|
||||||
fill_DRB_configList(&ctxt, ue_context_p, xid);
|
fill_DRB_configList(&ctxt, ue_context_p, xid);
|
||||||
|
e1ap_bearer_setup_resp_t resp = {0};
|
||||||
|
resp.numPDUSessions = req->numPDUSessions;
|
||||||
|
for (int i = 0; i < resp.numPDUSessions; ++i) {
|
||||||
|
resp.pduSession[i].numDRBSetup = req->pduSession[i].numDRB2Setup;
|
||||||
|
for (int j = 0; j < req->pduSession[i].numDRB2Setup; j++) {
|
||||||
|
DRB_nGRAN_to_setup_t *req_drb = req->pduSession[i].DRBnGRanList + j;
|
||||||
|
DRB_nGRAN_setup_t *resp_drb = resp.pduSession[i].DRBnGRanList + j;
|
||||||
|
resp_drb->id = req_drb->id;
|
||||||
|
resp_drb->numQosFlowSetup = req_drb->numQosFlow2Setup;
|
||||||
|
for (int k = 0; k < resp_drb->numQosFlowSetup; k++)
|
||||||
|
resp_drb->qosFlows[k].id = req_drb->qosFlows[k].id;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
gNB_RRC_INST *rrc = RC.nrrrc[ctxt.module_id];
|
gNB_RRC_INST *rrc = RC.nrrrc[ctxt.module_id];
|
||||||
// Fixme: xid not random, but almost!
|
// Fixme: xid not random, but almost!
|
||||||
@@ -198,21 +211,26 @@ static void cucp_cuup_bearer_context_setup_direct(e1ap_bearer_setup_req_t *const
|
|||||||
int ret = drb_config_gtpu_create(&ctxt, ue_context_p, req, UE->DRB_configList, *SRB_configList2, rrc->e1_inst);
|
int ret = drb_config_gtpu_create(&ctxt, ue_context_p, req, UE->DRB_configList, *SRB_configList2, rrc->e1_inst);
|
||||||
if (ret < 0) AssertFatal(false, "Unable to configure DRB or to create GTP Tunnel\n");
|
if (ret < 0) AssertFatal(false, "Unable to configure DRB or to create GTP Tunnel\n");
|
||||||
|
|
||||||
|
// Used to store teids: if monolithic, will simply be NULL
|
||||||
if(!NODE_IS_CU(RC.nrrrc[ctxt.module_id]->node_type)) {
|
if(!NODE_IS_CU(RC.nrrrc[ctxt.module_id]->node_type)) {
|
||||||
rrc_gNB_generate_dedicatedRRCReconfiguration(&ctxt, ue_context_p, NULL);
|
// intentionally empty
|
||||||
} else {
|
} else {
|
||||||
e1ap_bearer_setup_resp_t resp; // Used to store teids
|
|
||||||
int remote_port = RC.nrrrc[ctxt.module_id]->eth_params_s.remote_portd;
|
int remote_port = RC.nrrrc[ctxt.module_id]->eth_params_s.remote_portd;
|
||||||
in_addr_t my_addr = inet_addr(RC.nrrrc[ctxt.module_id]->eth_params_s.my_addr);
|
in_addr_t my_addr = inet_addr(RC.nrrrc[ctxt.module_id]->eth_params_s.my_addr);
|
||||||
instance_t gtpInst = getCxt(CUtype, instance)->gtpInst;
|
instance_t gtpInst = getCxt(CUtype, instance)->gtpInst;
|
||||||
// GTP tunnel for DL
|
// GTP tunnel for DL
|
||||||
fill_e1ap_bearer_setup_resp(&resp, req, gtpInst, UE->rnti, remote_port, my_addr);
|
fill_e1ap_bearer_setup_resp(&resp, req, gtpInst, UE->rnti, remote_port, my_addr);
|
||||||
|
|
||||||
prepare_and_send_ue_context_modification_f1(ue_context_p, &resp);
|
|
||||||
}
|
}
|
||||||
|
// actually, we should receive the corresponding context setup response
|
||||||
|
// message at the RRC and always react to this one. So in the following, we
|
||||||
|
// just call the corresponding message handler
|
||||||
|
prepare_and_send_ue_context_modification_f1(ue_context_p, &resp);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void cucp_cuup_bearer_context_mod_direct(e1ap_bearer_setup_req_t *const req, instance_t instance, uint8_t xid) {
|
static void cucp_cuup_bearer_context_mod_direct(e1ap_bearer_setup_req_t *const req, instance_t instance, uint8_t xid) {
|
||||||
|
// only update GTP tunnels if it is really a CU
|
||||||
|
if (!NODE_IS_CU(RC.nrrrc[0]->node_type))
|
||||||
|
return;
|
||||||
instance_t gtpInst = getCxt(CUtype, instance)->gtpInst;
|
instance_t gtpInst = getCxt(CUtype, instance)->gtpInst;
|
||||||
CU_update_UP_DL_tunnel(req, gtpInst, req->rnti);
|
CU_update_UP_DL_tunnel(req, gtpInst, req->rnti);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -26,6 +26,7 @@
|
|||||||
#include "f1ap_messages_types.h"
|
#include "f1ap_messages_types.h"
|
||||||
|
|
||||||
typedef void (*ue_context_setup_request_func_t)(const f1ap_ue_context_setup_t *req);
|
typedef void (*ue_context_setup_request_func_t)(const f1ap_ue_context_setup_t *req);
|
||||||
|
typedef void (*ue_context_modification_request_func_t)(const f1ap_ue_context_modif_req_t *req);
|
||||||
typedef void (*ue_context_release_command_func_t)(const f1ap_ue_context_release_cmd_t *cmd);
|
typedef void (*ue_context_release_command_func_t)(const f1ap_ue_context_release_cmd_t *cmd);
|
||||||
|
|
||||||
typedef void (*dl_rrc_message_transfer_func_t)(module_id_t module_id, const f1ap_dl_rrc_message_t *dl_rrc);
|
typedef void (*dl_rrc_message_transfer_func_t)(module_id_t module_id, const f1ap_dl_rrc_message_t *dl_rrc);
|
||||||
|
|||||||
@@ -34,6 +34,7 @@ static void dl_rrc_message_transfer_direct(module_id_t module_id, const f1ap_dl_
|
|||||||
void mac_rrc_dl_direct_init(nr_mac_rrc_dl_if_t *mac_rrc)
|
void mac_rrc_dl_direct_init(nr_mac_rrc_dl_if_t *mac_rrc)
|
||||||
{
|
{
|
||||||
mac_rrc->ue_context_setup_request = ue_context_setup_request;
|
mac_rrc->ue_context_setup_request = ue_context_setup_request;
|
||||||
|
mac_rrc->ue_context_modification_request = ue_context_modification_request;
|
||||||
mac_rrc->ue_context_release_command = ue_context_release_command;
|
mac_rrc->ue_context_release_command = ue_context_release_command;
|
||||||
mac_rrc->dl_rrc_message_transfer = dl_rrc_message_transfer_direct;
|
mac_rrc->dl_rrc_message_transfer = dl_rrc_message_transfer_direct;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -30,6 +30,38 @@ static void ue_context_setup_request_f1ap(const f1ap_ue_context_setup_t *req)
|
|||||||
f1ap_ue_context_setup_t *f1ap_msg = &F1AP_UE_CONTEXT_SETUP_REQ(msg);
|
f1ap_ue_context_setup_t *f1ap_msg = &F1AP_UE_CONTEXT_SETUP_REQ(msg);
|
||||||
*f1ap_msg = *req;
|
*f1ap_msg = *req;
|
||||||
AssertFatal(req->cu_to_du_rrc_information == NULL, "cu_to_du_rrc_information not supported yet\n");
|
AssertFatal(req->cu_to_du_rrc_information == NULL, "cu_to_du_rrc_information not supported yet\n");
|
||||||
|
AssertFatal(req->drbs_to_be_setup == NULL, "drbs_to_be_setup not supported yet\n");
|
||||||
|
AssertFatal(req->srbs_to_be_setup == NULL, "drbs_to_be_setup not supported yet\n");
|
||||||
|
if (req->rrc_container_length > 0) {
|
||||||
|
f1ap_msg->rrc_container = calloc(req->rrc_container_length, sizeof(*f1ap_msg->rrc_container));
|
||||||
|
AssertFatal(f1ap_msg->rrc_container != NULL, "out of memory\n");
|
||||||
|
f1ap_msg->rrc_container_length = req->rrc_container_length;
|
||||||
|
memcpy(f1ap_msg->rrc_container, req->rrc_container, req->rrc_container_length);
|
||||||
|
}
|
||||||
|
itti_send_msg_to_task(TASK_CU_F1, 0, msg);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void ue_context_modification_request_f1ap(const f1ap_ue_context_modif_req_t *req)
|
||||||
|
{
|
||||||
|
MessageDef *msg = itti_alloc_new_message(TASK_RRC_GNB, 0, F1AP_UE_CONTEXT_MODIFICATION_REQ);
|
||||||
|
f1ap_ue_context_modif_req_t *f1ap_msg = &F1AP_UE_CONTEXT_MODIFICATION_REQ(msg);
|
||||||
|
*f1ap_msg = *req;
|
||||||
|
AssertFatal(req->cu_to_du_rrc_information == NULL, "cu_to_du_rrc_information not supported yet\n");
|
||||||
|
AssertFatal(req->drbs_to_be_modified_length == 0, "drbs_to_be_modified not supported yet\n");
|
||||||
|
if (req->drbs_to_be_setup_length > 0) {
|
||||||
|
int n = req->drbs_to_be_setup_length;
|
||||||
|
f1ap_msg->drbs_to_be_setup_length = n;
|
||||||
|
f1ap_msg->drbs_to_be_setup = calloc(n, sizeof(*f1ap_msg->drbs_to_be_setup));
|
||||||
|
AssertFatal(f1ap_msg->drbs_to_be_setup != NULL, "out of memory\n");
|
||||||
|
memcpy(f1ap_msg->drbs_to_be_setup, req->drbs_to_be_setup, n * sizeof(*f1ap_msg->drbs_to_be_setup));
|
||||||
|
}
|
||||||
|
if (req->srbs_to_be_setup_length > 0) {
|
||||||
|
int n = req->srbs_to_be_setup_length;
|
||||||
|
f1ap_msg->srbs_to_be_setup_length = n;
|
||||||
|
f1ap_msg->srbs_to_be_setup = calloc(n, sizeof(*f1ap_msg->srbs_to_be_setup));
|
||||||
|
AssertFatal(f1ap_msg->srbs_to_be_setup != NULL, "out of memory\n");
|
||||||
|
memcpy(f1ap_msg->srbs_to_be_setup, req->srbs_to_be_setup, n * sizeof(*f1ap_msg->srbs_to_be_setup));
|
||||||
|
}
|
||||||
if (req->rrc_container_length > 0) {
|
if (req->rrc_container_length > 0) {
|
||||||
f1ap_msg->rrc_container = calloc(req->rrc_container_length, sizeof(*f1ap_msg->rrc_container));
|
f1ap_msg->rrc_container = calloc(req->rrc_container_length, sizeof(*f1ap_msg->rrc_container));
|
||||||
AssertFatal(f1ap_msg->rrc_container != NULL, "out of memory\n");
|
AssertFatal(f1ap_msg->rrc_container != NULL, "out of memory\n");
|
||||||
@@ -66,6 +98,7 @@ static void dl_rrc_message_transfer_f1ap(module_id_t module_id, const f1ap_dl_rr
|
|||||||
void mac_rrc_dl_f1ap_init(nr_mac_rrc_dl_if_t *mac_rrc)
|
void mac_rrc_dl_f1ap_init(nr_mac_rrc_dl_if_t *mac_rrc)
|
||||||
{
|
{
|
||||||
mac_rrc->ue_context_setup_request = ue_context_setup_request_f1ap;
|
mac_rrc->ue_context_setup_request = ue_context_setup_request_f1ap;
|
||||||
|
mac_rrc->ue_context_modification_request = ue_context_modification_request_f1ap;
|
||||||
mac_rrc->ue_context_release_command = ue_context_release_command_f1ap;
|
mac_rrc->ue_context_release_command = ue_context_release_command_f1ap;
|
||||||
mac_rrc->dl_rrc_message_transfer = dl_rrc_message_transfer_f1ap;
|
mac_rrc->dl_rrc_message_transfer = dl_rrc_message_transfer_f1ap;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -379,6 +379,7 @@ typedef struct {
|
|||||||
|
|
||||||
typedef struct nr_mac_rrc_dl_if_s {
|
typedef struct nr_mac_rrc_dl_if_s {
|
||||||
ue_context_setup_request_func_t ue_context_setup_request;
|
ue_context_setup_request_func_t ue_context_setup_request;
|
||||||
|
ue_context_modification_request_func_t ue_context_modification_request;
|
||||||
ue_context_release_command_func_t ue_context_release_command;
|
ue_context_release_command_func_t ue_context_release_command;
|
||||||
dl_rrc_message_transfer_func_t dl_rrc_message_transfer;
|
dl_rrc_message_transfer_func_t dl_rrc_message_transfer;
|
||||||
} nr_mac_rrc_dl_if_t;
|
} nr_mac_rrc_dl_if_t;
|
||||||
|
|||||||
@@ -142,11 +142,7 @@ rrc_gNB_generate_dedicatedRRCReconfiguration_release(
|
|||||||
uint32_t nas_length,
|
uint32_t nas_length,
|
||||||
uint8_t *nas_buffer);
|
uint8_t *nas_buffer);
|
||||||
|
|
||||||
void
|
void rrc_gNB_generate_dedicatedRRCReconfiguration(const protocol_ctxt_t *const ctxt_pP, rrc_gNB_ue_context_t *ue_context_pP);
|
||||||
rrc_gNB_generate_dedicatedRRCReconfiguration(
|
|
||||||
const protocol_ctxt_t *const ctxt_pP,
|
|
||||||
rrc_gNB_ue_context_t *ue_context_pP,
|
|
||||||
NR_CellGroupConfig_t *cell_groupConfig_from_DU);
|
|
||||||
|
|
||||||
void bearer_context_setup_direct(e1ap_bearer_setup_req_t *req,
|
void bearer_context_setup_direct(e1ap_bearer_setup_req_t *req,
|
||||||
instance_t instance);
|
instance_t instance);
|
||||||
|
|||||||
+96
-288
@@ -112,23 +112,6 @@ mui_t rrc_gNB_mui = 0;
|
|||||||
///---------------------------------------------------------------------------------------------------------------///
|
///---------------------------------------------------------------------------------------------------------------///
|
||||||
///---------------------------------------------------------------------------------------------------------------///
|
///---------------------------------------------------------------------------------------------------------------///
|
||||||
|
|
||||||
bool DURecvCb(protocol_ctxt_t *ctxt_pP,
|
|
||||||
const srb_flag_t srb_flagP,
|
|
||||||
const rb_id_t rb_idP,
|
|
||||||
const mui_t muiP,
|
|
||||||
const confirm_t confirmP,
|
|
||||||
const sdu_size_t sdu_buffer_sizeP,
|
|
||||||
unsigned char *const sdu_buffer_pP,
|
|
||||||
const pdcp_transmission_mode_t modeP,
|
|
||||||
const uint32_t *sourceL2Id,
|
|
||||||
const uint32_t *destinationL2Id) {
|
|
||||||
// The buffer comes from the stack in gtp-u thread, we have a make a separate buffer to enqueue in a inter-thread message queue
|
|
||||||
mem_block_t *sdu=get_free_mem_block(sdu_buffer_sizeP, __func__);
|
|
||||||
memcpy(sdu->data, sdu_buffer_pP, sdu_buffer_sizeP);
|
|
||||||
du_rlc_data_req(ctxt_pP,srb_flagP, false, rb_idP,muiP, confirmP, sdu_buffer_sizeP, sdu);
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
static void nr_rrc_addmod_srbs(int rnti,
|
static void nr_rrc_addmod_srbs(int rnti,
|
||||||
const NR_SRB_ToAddModList_t *srb_list,
|
const NR_SRB_ToAddModList_t *srb_list,
|
||||||
const struct NR_CellGroupConfig__rlc_BearerToAddModList *bearer_list)
|
const struct NR_CellGroupConfig__rlc_BearerToAddModList *bearer_list)
|
||||||
@@ -642,17 +625,10 @@ void fill_DRB_configList(const protocol_ctxt_t *const ctxt_pP, rrc_gNB_ue_contex
|
|||||||
}
|
}
|
||||||
|
|
||||||
//-----------------------------------------------------------------------------
|
//-----------------------------------------------------------------------------
|
||||||
void
|
void rrc_gNB_generate_dedicatedRRCReconfiguration(const protocol_ctxt_t *const ctxt_pP, rrc_gNB_ue_context_t *ue_context_pP)
|
||||||
rrc_gNB_generate_dedicatedRRCReconfiguration(
|
|
||||||
const protocol_ctxt_t *const ctxt_pP,
|
|
||||||
rrc_gNB_ue_context_t *ue_context_pP,
|
|
||||||
NR_CellGroupConfig_t *cell_groupConfig_from_DU
|
|
||||||
)
|
|
||||||
//-----------------------------------------------------------------------------
|
//-----------------------------------------------------------------------------
|
||||||
{
|
{
|
||||||
gNB_RRC_INST *rrc = RC.nrrrc[ctxt_pP->module_id];
|
gNB_RRC_INST *rrc = RC.nrrrc[ctxt_pP->module_id];
|
||||||
long drb_priority[NGAP_MAX_DRBS_PER_UE];
|
|
||||||
NR_CellGroupConfig_t *cellGroupConfig = NULL;
|
|
||||||
int xid = -1;
|
int xid = -1;
|
||||||
|
|
||||||
int drb_id_to_setup_start = 1;
|
int drb_id_to_setup_start = 1;
|
||||||
@@ -683,7 +659,6 @@ rrc_gNB_generate_dedicatedRRCReconfiguration(
|
|||||||
}
|
}
|
||||||
|
|
||||||
xid = ue_p->pduSession[j].xid;
|
xid = ue_p->pduSession[j].xid;
|
||||||
drb_priority[DRB_config->drb_Identity - 1] = 13; // For now, we assume only one drb per pdu sessions with a default preiority (will be dynamique in future)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* If list is empty free the list and reset the address */
|
/* If list is empty free the list and reset the address */
|
||||||
@@ -692,20 +667,7 @@ rrc_gNB_generate_dedicatedRRCReconfiguration(
|
|||||||
dedicatedNAS_MessageList = NULL;
|
dedicatedNAS_MessageList = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
if(cell_groupConfig_from_DU == NULL){
|
NR_CellGroupConfig_t *cellGroupConfig = ue_p->masterCellGroup;
|
||||||
cellGroupConfig = calloc(1, sizeof(NR_CellGroupConfig_t));
|
|
||||||
// FIXME: fill_mastercellGroupConfig() won't fill the right priorities
|
|
||||||
fill_mastercellGroupConfig(cellGroupConfig,
|
|
||||||
ue_p->masterCellGroup,
|
|
||||||
rrc->um_on_default_drb,
|
|
||||||
(drb_id_to_setup_start < 2) ? 1 : 0,
|
|
||||||
DRB_configList,
|
|
||||||
drb_priority);
|
|
||||||
}
|
|
||||||
else{
|
|
||||||
LOG_I(NR_RRC, "Master cell group originating from the DU \n");
|
|
||||||
cellGroupConfig = cell_groupConfig_from_DU;
|
|
||||||
}
|
|
||||||
|
|
||||||
AssertFatal(xid > -1, "Invalid xid %d. No PDU sessions setup to configure.\n", xid);
|
AssertFatal(xid > -1, "Invalid xid %d. No PDU sessions setup to configure.\n", xid);
|
||||||
NR_SRB_ToAddModList_t *SRB_configList2 = NULL;
|
NR_SRB_ToAddModList_t *SRB_configList2 = NULL;
|
||||||
@@ -2067,6 +2029,7 @@ static void handle_rrcReconfigurationComplete(const protocol_ctxt_t *const ctxt_
|
|||||||
uint8_t xid = reconfig_complete->rrc_TransactionIdentifier;
|
uint8_t xid = reconfig_complete->rrc_TransactionIdentifier;
|
||||||
rrc_gNB_process_RRCReconfigurationComplete(ctxt_pP, ue_context_p, xid);
|
rrc_gNB_process_RRCReconfigurationComplete(ctxt_pP, ue_context_p, xid);
|
||||||
|
|
||||||
|
bool successful_reconfig = true;
|
||||||
if (get_softmodem_params()->sa) {
|
if (get_softmodem_params()->sa) {
|
||||||
switch (UE->xids[xid]) {
|
switch (UE->xids[xid]) {
|
||||||
case RRC_PDUSESSION_RELEASE: {
|
case RRC_PDUSESSION_RELEASE: {
|
||||||
@@ -2085,10 +2048,29 @@ static void handle_rrcReconfigurationComplete(const protocol_ctxt_t *const ctxt_
|
|||||||
case RRC_FIRST_RECONF:
|
case RRC_FIRST_RECONF:
|
||||||
rrc_gNB_send_NGAP_INITIAL_CONTEXT_SETUP_RESP(ctxt_pP, ue_context_p);
|
rrc_gNB_send_NGAP_INITIAL_CONTEXT_SETUP_RESP(ctxt_pP, ue_context_p);
|
||||||
break;
|
break;
|
||||||
|
case RRC_DEFAULT_RECONF:
|
||||||
|
/* nothing to do */
|
||||||
|
break;
|
||||||
default:
|
default:
|
||||||
LOG_E(RRC, "Received unexpected xid: %d\n", xid);
|
LOG_E(RRC, "Received unexpected xid: %d\n", xid);
|
||||||
|
successful_reconfig = false;
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
gNB_RRC_INST *rrc = RC.nrrrc[0];
|
||||||
|
f1ap_ue_context_modif_req_t ue_context_modif_req = {
|
||||||
|
.gNB_CU_ue_id = 0xffffffff, /* filled by F1 for the moment */
|
||||||
|
.gNB_DU_ue_id = 0xffffffff, /* filled by F1 for the moment */
|
||||||
|
.rnti = UE->rnti,
|
||||||
|
.mcc = rrc->configuration.mcc[0],
|
||||||
|
.mnc = rrc->configuration.mnc[0],
|
||||||
|
.mnc_digit_length = rrc->configuration.mnc_digit_length[0],
|
||||||
|
.nr_cellid = rrc->nr_cellid,
|
||||||
|
.servCellId = 0, /* TODO: correct value? */
|
||||||
|
.ReconfigComplOutcome = successful_reconfig ? RRCreconf_success : RRCreconf_failure,
|
||||||
|
};
|
||||||
|
rrc->mac_rrc.ue_context_modification_request(&ue_context_modif_req);
|
||||||
}
|
}
|
||||||
//-----------------------------------------------------------------------------
|
//-----------------------------------------------------------------------------
|
||||||
int rrc_gNB_decode_dcch(const protocol_ctxt_t *const ctxt_pP,
|
int rrc_gNB_decode_dcch(const protocol_ctxt_t *const ctxt_pP,
|
||||||
@@ -2357,158 +2339,9 @@ void rrc_gNB_process_dc_overall_timeout(const module_id_t gnb_mod_idP, x2ap_ENDC
|
|||||||
rrc_remove_nsa_user(rrc, m->rnti);
|
rrc_remove_nsa_user(rrc, m->rnti);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void rrc_DU_process_ue_context_modification_request(MessageDef *msg_p, instance_t instance)
|
|
||||||
{
|
|
||||||
f1ap_ue_context_setup_t * req=&F1AP_UE_CONTEXT_MODIFICATION_REQ(msg_p);
|
|
||||||
protocol_ctxt_t ctxt = {.rntiMaybeUEid = req->rnti, .module_id = instance, .instance = instance, .enb_flag = 1, .eNB_index = instance};
|
|
||||||
gNB_RRC_INST *rrc = RC.nrrrc[ctxt.module_id];
|
|
||||||
gNB_MAC_INST *mac = RC.nrmac[ctxt.module_id];
|
|
||||||
rrc_gNB_ue_context_t *ue_context_p = rrc_gNB_get_ue_context_by_rnti(rrc, req->rnti);
|
|
||||||
gNB_RRC_UE_t *UE = &ue_context_p->ue_context;
|
|
||||||
MessageDef *message_p;
|
|
||||||
message_p = itti_alloc_new_message (TASK_RRC_GNB, 0, F1AP_UE_CONTEXT_MODIFICATION_RESP);
|
|
||||||
f1ap_ue_context_setup_t * resp=&F1AP_UE_CONTEXT_MODIFICATION_RESP(message_p);
|
|
||||||
uint32_t incoming_teid = 0;
|
|
||||||
NR_CellGroupConfig_t *cellGroupConfig = NULL;
|
|
||||||
|
|
||||||
/* Configure SRB2 */
|
|
||||||
NR_SRB_ToAddMod_t *SRB2_config = NULL;
|
|
||||||
NR_SRB_ToAddModList_t *SRB_configList = NULL;
|
|
||||||
uint8_t SRBs_before_new_addition = 0;
|
|
||||||
|
|
||||||
if(req->srbs_to_be_setup_length>0){
|
|
||||||
if (UE->SRB_configList == NULL) {
|
|
||||||
LOG_W(NR_RRC, "The SRB list of the UE context is empty before the addition of new SRB at the DU \n");
|
|
||||||
UE->SRB_configList = CALLOC(1, sizeof(*UE->SRB_configList));
|
|
||||||
}
|
|
||||||
SRB_configList = UE->SRB_configList;
|
|
||||||
SRBs_before_new_addition = SRB_configList->list.count;
|
|
||||||
for (int i=0; i<req->srbs_to_be_setup_length; i++){
|
|
||||||
SRB2_config = CALLOC(1, sizeof(*SRB2_config));
|
|
||||||
SRB2_config->srb_Identity = req->srbs_to_be_setup[i].srb_id;
|
|
||||||
asn1cSeqAdd(&SRB_configList->list, SRB2_config);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Configure DRB */
|
|
||||||
NR_DRB_ToAddMod_t *DRB_config = NULL;
|
|
||||||
NR_DRB_ToAddModList_t *DRB_configList = NULL;
|
|
||||||
int drb_id_to_setup_start = 0;
|
|
||||||
long drb_priority[NGAP_MAX_DRBS_PER_UE];
|
|
||||||
if(req->drbs_to_be_setup_length>0){
|
|
||||||
if (UE->DRB_configList == NULL) {
|
|
||||||
UE->DRB_configList = CALLOC(1, sizeof(*UE->DRB_configList));
|
|
||||||
}
|
|
||||||
DRB_configList = UE->DRB_configList;
|
|
||||||
for (int i=0; i<req->drbs_to_be_setup_length; i++){
|
|
||||||
DRB_config = CALLOC(1, sizeof(*DRB_config));
|
|
||||||
DRB_config->drb_Identity = req->drbs_to_be_setup[i].drb_id;
|
|
||||||
if (drb_id_to_setup_start == 0) drb_id_to_setup_start = DRB_config->drb_Identity;
|
|
||||||
asn1cSeqAdd(&DRB_configList->list, DRB_config);
|
|
||||||
f1ap_drb_to_be_setup_t drb_p = req->drbs_to_be_setup[i];
|
|
||||||
transport_layer_addr_t addr;
|
|
||||||
memcpy(addr.buffer, &drb_p.up_ul_tnl[0].tl_address, sizeof(drb_p.up_ul_tnl[0].tl_address));
|
|
||||||
addr.length=sizeof(drb_p.up_ul_tnl[0].tl_address)*8;
|
|
||||||
extern instance_t DUuniqInstance;
|
|
||||||
if (!drb_id_to_setup_start) drb_id_to_setup_start = drb_p.drb_id;
|
|
||||||
incoming_teid = newGtpuCreateTunnel(DUuniqInstance,
|
|
||||||
req->rnti,
|
|
||||||
drb_p.drb_id,
|
|
||||||
drb_p.drb_id,
|
|
||||||
drb_p.up_ul_tnl[0].teid,
|
|
||||||
-1, // no qfi
|
|
||||||
addr,
|
|
||||||
drb_p.up_ul_tnl[0].port,
|
|
||||||
DURecvCb,
|
|
||||||
NULL);
|
|
||||||
/* TODO: hardcoded to 13 for the time being, to be changed? */
|
|
||||||
drb_priority[DRB_config->drb_Identity-1] = 13;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if(req->srbs_to_be_setup_length>0 || req->drbs_to_be_setup_length>0){
|
|
||||||
cellGroupConfig = calloc(1, sizeof(NR_CellGroupConfig_t));
|
|
||||||
fill_mastercellGroupConfig(cellGroupConfig,
|
|
||||||
UE->masterCellGroup,
|
|
||||||
rrc->um_on_default_drb,
|
|
||||||
drb_id_to_setup_start < 2 ? 1 : 0,
|
|
||||||
DRB_configList,
|
|
||||||
drb_priority);
|
|
||||||
apply_macrlc_config(rrc, ue_context_p, &ctxt);
|
|
||||||
}
|
|
||||||
if(req->ReconfigComplOutcome == RRCreconf_failure){
|
|
||||||
LOG_W(NR_RRC, "CU reporting RRC Reconfiguration failure \n");
|
|
||||||
}
|
|
||||||
else if(req->ReconfigComplOutcome == RRCreconf_success){
|
|
||||||
LOG_I(NR_RRC, "CU reporting RRC Reconfiguration success \n");
|
|
||||||
if (UE->DRB_configList != NULL) {
|
|
||||||
LOG_I(NR_RRC, "Send first DDD buffer status reporting towards the CU through an ITTI message to gtp-u \n");
|
|
||||||
uint8_t drb_id = UE->DRB_configList->list.array[0]->drb_Identity;
|
|
||||||
rnti_t rnti = UE->rnti;
|
|
||||||
int rlc_tx_buffer_space = nr_rlc_get_available_tx_space(rnti, drb_id + 3);
|
|
||||||
LOG_I(NR_RRC, "Reported in DDD drb_id:%d, rnti:%d\n", drb_id, rnti);
|
|
||||||
MessageDef *msg = itti_alloc_new_message_sized(TASK_RRC_GNB, 0, GTPV1U_DU_BUFFER_REPORT_REQ,
|
|
||||||
sizeof(gtpv1u_tunnel_data_req_t));
|
|
||||||
gtpv1u_DU_buffer_report_req_t *req=>PV1U_DU_BUFFER_REPORT_REQ(msg);
|
|
||||||
req->pdusession_id = drb_id;
|
|
||||||
req->ue_id = rnti;
|
|
||||||
req->buffer_availability = rlc_tx_buffer_space; //10000000; //Hardcoding to be removed and read the actual RLC buffer availability instead
|
|
||||||
extern instance_t DUuniqInstance;
|
|
||||||
itti_send_msg_to_task(TASK_GTPV1_U, DUuniqInstance, msg);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Fill the UE context setup response ITTI message to send to F1AP */
|
|
||||||
resp->gNB_CU_ue_id = req->gNB_CU_ue_id;
|
|
||||||
resp->rnti = ctxt.rntiMaybeUEid;
|
|
||||||
if(DRB_configList){
|
|
||||||
if(DRB_configList->list.count > 0){
|
|
||||||
resp->drbs_to_be_setup = calloc(1,DRB_configList->list.count*sizeof(f1ap_drb_to_be_setup_t));
|
|
||||||
resp->drbs_to_be_setup_length = DRB_configList->list.count;
|
|
||||||
for (int i=0; i<DRB_configList->list.count; i++){
|
|
||||||
resp->drbs_to_be_setup[i].drb_id = DRB_configList->list.array[i]->drb_Identity;
|
|
||||||
resp->drbs_to_be_setup[i].rlc_mode = RLC_MODE_AM;
|
|
||||||
resp->drbs_to_be_setup[i].up_dl_tnl[0].teid = incoming_teid;
|
|
||||||
resp->drbs_to_be_setup[i].up_dl_tnl[0].tl_address = inet_addr(mac->eth_params_n.my_addr);
|
|
||||||
resp->drbs_to_be_setup[i].up_dl_tnl_length = 1;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else{
|
|
||||||
LOG_W(NR_RRC, "No DRB added upon reception of F1 UE context modification request with a DRB to setup list\n");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if(SRB_configList){
|
|
||||||
if(SRB_configList->list.count >0 && SRBs_before_new_addition < SRB_configList->list.count){
|
|
||||||
resp->srbs_to_be_setup = calloc(1,req->srbs_to_be_setup_length*sizeof(f1ap_srb_to_be_setup_t));
|
|
||||||
resp->srbs_to_be_setup_length = req->srbs_to_be_setup_length;
|
|
||||||
for (int i=SRBs_before_new_addition; i<SRB_configList->list.count; i++){
|
|
||||||
resp->srbs_to_be_setup[i-SRBs_before_new_addition].srb_id = SRB_configList->list.array[i]->srb_Identity;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else{
|
|
||||||
LOG_W(NR_RRC, "No SRB added upon reception of F1 UE Context modification request at the DU\n");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else{
|
|
||||||
LOG_W(NR_RRC, "No SRB added upon reception of F1 UE Context modification request at the DU\n");
|
|
||||||
}
|
|
||||||
|
|
||||||
//if(cellGroupConfig != NULL) {
|
|
||||||
resp->du_to_cu_rrc_information = calloc(1,sizeof(du_to_cu_rrc_information_t));
|
|
||||||
resp->du_to_cu_rrc_information->cellGroupConfig = calloc(1,1024);
|
|
||||||
asn_enc_rval_t enc_rval = uper_encode_to_buffer(&asn_DEF_NR_CellGroupConfig,
|
|
||||||
NULL,
|
|
||||||
UE->masterCellGroup, //(void *)cellGroupConfig,
|
|
||||||
resp->du_to_cu_rrc_information->cellGroupConfig,
|
|
||||||
1024);
|
|
||||||
resp->du_to_cu_rrc_information->cellGroupConfig_length = (enc_rval.encoded+7)>>3;
|
|
||||||
//}
|
|
||||||
itti_send_msg_to_task (TASK_DU_F1, ctxt.module_id, message_p);
|
|
||||||
}
|
|
||||||
|
|
||||||
static void rrc_CU_process_ue_context_setup_response(MessageDef *msg_p, instance_t instance)
|
static void rrc_CU_process_ue_context_setup_response(MessageDef *msg_p, instance_t instance)
|
||||||
{
|
{
|
||||||
f1ap_ue_context_setup_t * resp=&F1AP_UE_CONTEXT_SETUP_RESP(msg_p);
|
f1ap_ue_context_setup_t *resp = &F1AP_UE_CONTEXT_SETUP_RESP(msg_p);
|
||||||
gNB_RRC_INST *rrc = RC.nrrrc[instance];
|
gNB_RRC_INST *rrc = RC.nrrrc[instance];
|
||||||
rrc_gNB_ue_context_t *ue_context_p = rrc_gNB_get_ue_context_by_rnti(rrc, resp->rnti);
|
rrc_gNB_ue_context_t *ue_context_p = rrc_gNB_get_ue_context_by_rnti(rrc, resp->rnti);
|
||||||
gNB_RRC_UE_t *UE = &ue_context_p->ue_context;
|
gNB_RRC_UE_t *UE = &ue_context_p->ue_context;
|
||||||
@@ -2566,75 +2399,52 @@ static void rrc_CU_process_ue_context_release_complete(MessageDef *msg_p)
|
|||||||
|
|
||||||
static void rrc_CU_process_ue_context_modification_response(MessageDef *msg_p, instance_t instance)
|
static void rrc_CU_process_ue_context_modification_response(MessageDef *msg_p, instance_t instance)
|
||||||
{
|
{
|
||||||
f1ap_ue_context_setup_t *resp=&F1AP_UE_CONTEXT_SETUP_RESP(msg_p);
|
f1ap_ue_context_modif_resp_t *resp = &F1AP_UE_CONTEXT_MODIFICATION_RESP(msg_p);
|
||||||
protocol_ctxt_t ctxt = {.rntiMaybeUEid = resp->rnti, .module_id = instance, .instance = instance, .enb_flag = 1, .eNB_index = instance};
|
protocol_ctxt_t ctxt = {.rntiMaybeUEid = resp->rnti, .module_id = instance, .instance = instance, .enb_flag = 1, .eNB_index = instance};
|
||||||
gNB_RRC_INST *rrc = RC.nrrrc[ctxt.module_id];
|
gNB_RRC_INST *rrc = RC.nrrrc[ctxt.module_id];
|
||||||
rrc_gNB_ue_context_t *ue_context_p = rrc_gNB_get_ue_context_by_rnti(rrc, resp->rnti);
|
rrc_gNB_ue_context_t *ue_context_p = rrc_gNB_get_ue_context_by_rnti(rrc, resp->rnti);
|
||||||
gNB_RRC_UE_t *UE = &ue_context_p->ue_context;
|
gNB_RRC_UE_t *UE = &ue_context_p->ue_context;
|
||||||
|
|
||||||
e1ap_bearer_setup_req_t req = {0};
|
if (resp->drbs_to_be_setup_length > 0) {
|
||||||
req.numPDUSessionsMod = UE->nb_of_pdusessions;
|
e1ap_bearer_setup_req_t req = {0};
|
||||||
req.gNB_cu_cp_ue_id = UE->gNB_ue_ngap_id;
|
req.numPDUSessionsMod = UE->nb_of_pdusessions;
|
||||||
req.rnti = UE->rnti;
|
req.gNB_cu_cp_ue_id = UE->gNB_ue_ngap_id;
|
||||||
for (int i=0; i < req.numPDUSessionsMod; i++) {
|
req.rnti = UE->rnti;
|
||||||
req.pduSessionMod[i].numDRB2Modify = resp->drbs_to_be_setup_length;
|
for (int i = 0; i < req.numPDUSessionsMod; i++) {
|
||||||
for (int j=0; j < resp->drbs_to_be_setup_length; j++) {
|
req.pduSessionMod[i].numDRB2Modify = resp->drbs_to_be_setup_length;
|
||||||
f1ap_drb_to_be_setup_t *drb_f1 = resp->drbs_to_be_setup + j;
|
for (int j = 0; j < resp->drbs_to_be_setup_length; j++) {
|
||||||
DRB_nGRAN_to_setup_t *drb_e1 = req.pduSessionMod[i].DRBnGRanModList + j;
|
f1ap_drb_to_be_setup_t *drb_f1 = resp->drbs_to_be_setup + j;
|
||||||
|
DRB_nGRAN_to_setup_t *drb_e1 = req.pduSessionMod[i].DRBnGRanModList + j;
|
||||||
|
|
||||||
drb_e1->id = drb_f1->drb_id;
|
drb_e1->id = drb_f1->drb_id;
|
||||||
drb_e1->numDlUpParam = drb_f1->up_dl_tnl_length;
|
drb_e1->numDlUpParam = drb_f1->up_dl_tnl_length;
|
||||||
drb_e1->DlUpParamList[0].tlAddress = drb_f1->up_dl_tnl[0].tl_address;
|
drb_e1->DlUpParamList[0].tlAddress = drb_f1->up_dl_tnl[0].tl_address;
|
||||||
drb_e1->DlUpParamList[0].teId = drb_f1->up_dl_tnl[0].teid;
|
drb_e1->DlUpParamList[0].teId = drb_f1->up_dl_tnl[0].teid;
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// send the F1 response message up to update F1-U tunnel info
|
|
||||||
// it seems the rrc transaction id (xid) is not needed here
|
|
||||||
rrc->cucp_cuup.bearer_context_mod(&req, instance, 0);
|
|
||||||
|
|
||||||
NR_CellGroupConfig_t *cellGroupConfig = NULL;
|
|
||||||
|
|
||||||
if(resp->du_to_cu_rrc_information->cellGroupConfig!=NULL){
|
|
||||||
asn_dec_rval_t dec_rval = uper_decode_complete( NULL,
|
|
||||||
&asn_DEF_NR_CellGroupConfig,
|
|
||||||
(void **)&cellGroupConfig,
|
|
||||||
(uint8_t *)resp->du_to_cu_rrc_information->cellGroupConfig,
|
|
||||||
(int) resp->du_to_cu_rrc_information->cellGroupConfig_length);
|
|
||||||
|
|
||||||
if((dec_rval.code != RC_OK) && (dec_rval.consumed == 0)) {
|
|
||||||
AssertFatal(1==0,"Cell group config decode error\n");
|
|
||||||
// free the memory
|
|
||||||
SEQUENCE_free( &asn_DEF_NR_CellGroupConfig, cellGroupConfig, 1 );
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
//xer_fprint(stdout,&asn_DEF_NR_CellGroupConfig, cellGroupConfig);
|
|
||||||
|
|
||||||
if (UE->masterCellGroup == NULL) {
|
|
||||||
UE->masterCellGroup = calloc(1, sizeof(NR_CellGroupConfig_t));
|
|
||||||
}
|
|
||||||
|
|
||||||
if(cellGroupConfig->rlc_BearerToAddModList!=NULL){
|
|
||||||
if (UE->masterCellGroup->rlc_BearerToAddModList != NULL) {
|
|
||||||
int ue_ctxt_rlc_Bearers = UE->masterCellGroup->rlc_BearerToAddModList->list.count;
|
|
||||||
for(int i=ue_ctxt_rlc_Bearers; i<ue_ctxt_rlc_Bearers + cellGroupConfig->rlc_BearerToAddModList->list.count; i++){
|
|
||||||
asn1cSeqAdd(&UE->masterCellGroup->rlc_BearerToAddModList->list, cellGroupConfig->rlc_BearerToAddModList->list.array[i - ue_ctxt_rlc_Bearers]);
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
LOG_W(NR_RRC, "Empty rlc_BearerToAddModList at ue_context of the CU before filling the updates from UE context setup response \n");
|
|
||||||
UE->masterCellGroup->rlc_BearerToAddModList = calloc(1, sizeof(*cellGroupConfig->rlc_BearerToAddModList));
|
|
||||||
memcpy(UE->masterCellGroup->rlc_BearerToAddModList, cellGroupConfig->rlc_BearerToAddModList, sizeof(*cellGroupConfig->rlc_BearerToAddModList));
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
LOG_I(NR_RRC, "Updated master cell group configuration stored at the UE context of the CU:\n");
|
|
||||||
if (LOG_DEBUGFLAG(DEBUG_ASN1)) {
|
// send the F1 response message up to update F1-U tunnel info
|
||||||
xer_fprint(stdout, &asn_DEF_NR_CellGroupConfig, UE->masterCellGroup);
|
// it seems the rrc transaction id (xid) is not needed here
|
||||||
|
rrc->cucp_cuup.bearer_context_mod(&req, instance, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (resp->du_to_cu_rrc_information != NULL && resp->du_to_cu_rrc_information->cellGroupConfig != NULL) {
|
||||||
|
LOG_W(RRC, "UE context modification response contains new CellGroupConfig for UE %04x, triggering reconfiguration\n", UE->rnti);
|
||||||
|
NR_CellGroupConfig_t *cellGroupConfig = NULL;
|
||||||
|
asn_dec_rval_t dec_rval = uper_decode_complete(NULL,
|
||||||
|
&asn_DEF_NR_CellGroupConfig,
|
||||||
|
(void **)&cellGroupConfig,
|
||||||
|
(uint8_t *)resp->du_to_cu_rrc_information->cellGroupConfig,
|
||||||
|
resp->du_to_cu_rrc_information->cellGroupConfig_length);
|
||||||
|
AssertFatal(dec_rval.code == RC_OK && dec_rval.consumed > 0, "Cell group config decode error\n");
|
||||||
|
|
||||||
|
if (UE->masterCellGroup) {
|
||||||
|
ASN_STRUCT_FREE(asn_DEF_NR_CellGroupConfig, UE->masterCellGroup);
|
||||||
|
LOG_I(RRC, "UE %04x replacing existing CellGroupConfig with new one received from DU\n", UE->rnti);
|
||||||
}
|
}
|
||||||
|
UE->masterCellGroup = cellGroupConfig;
|
||||||
|
|
||||||
rrc_gNB_generate_dedicatedRRCReconfiguration(&ctxt, ue_context_p, cellGroupConfig);
|
rrc_gNB_generate_dedicatedRRCReconfiguration(&ctxt, ue_context_p);
|
||||||
|
|
||||||
free(cellGroupConfig->rlc_BearerToAddModList);
|
|
||||||
free(cellGroupConfig);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -2817,46 +2627,48 @@ int rrc_gNB_process_e1_setup_req(e1ap_setup_req_t *req, instance_t instance) {
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
void prepare_and_send_ue_context_modification_f1(rrc_gNB_ue_context_t *ue_context_p,
|
void prepare_and_send_ue_context_modification_f1(rrc_gNB_ue_context_t *ue_context_p, e1ap_bearer_setup_resp_t *e1ap_resp)
|
||||||
e1ap_bearer_setup_resp_t *e1ap_resp) {
|
{
|
||||||
|
/* Generate a UE context modification request message towards the DU to
|
||||||
|
* instruct the DU for SRB2 and DRB configuration and get the updates on
|
||||||
|
* master cell group config from the DU*/
|
||||||
|
|
||||||
/*Generate a UE context modification request message towards the DU to instruct the DU
|
gNB_RRC_INST *rrc = RC.nrrrc[0];
|
||||||
*for SRB2 and DRB configuration and get the updates on master cell group config from the DU*/
|
|
||||||
gNB_RRC_UE_t *UE = &ue_context_p->ue_context;
|
gNB_RRC_UE_t *UE = &ue_context_p->ue_context;
|
||||||
|
|
||||||
protocol_ctxt_t ctxt = {0};
|
/* Instruction towards the DU for DRB configuration and tunnel creation */
|
||||||
PROTOCOL_CTXT_SET_BY_MODULE_ID(&ctxt, 0, GNB_FLAG_YES, UE->rnti, 0, 0, 0);
|
int nb_drb = e1ap_resp->pduSession[0].numDRBSetup;
|
||||||
// TODO: So many hard codings
|
f1ap_drb_to_be_setup_t drbs[nb_drb];
|
||||||
MessageDef *message_p;
|
for (int i = 0; i < nb_drb; i++) {
|
||||||
message_p = itti_alloc_new_message (TASK_RRC_GNB, 0, F1AP_UE_CONTEXT_MODIFICATION_REQ);
|
drbs[i].drb_id = e1ap_resp->pduSession[0].DRBnGRanList[i].id;
|
||||||
f1ap_ue_context_setup_t *req=&F1AP_UE_CONTEXT_MODIFICATION_REQ(message_p);
|
drbs[i].rlc_mode = rrc->um_on_default_drb ? RLC_MODE_UM : RLC_MODE_AM;
|
||||||
req->rnti = UE->rnti;
|
drbs[i].up_ul_tnl[0].tl_address = e1ap_resp->pduSession[0].DRBnGRanList[i].UpParamList[0].tlAddress;
|
||||||
req->mcc = RC.nrrrc[ctxt.module_id]->configuration.mcc[0];
|
drbs[i].up_ul_tnl[0].port = rrc->eth_params_s.my_portd;
|
||||||
req->mnc = RC.nrrrc[ctxt.module_id]->configuration.mnc[0];
|
drbs[i].up_ul_tnl[0].teid = e1ap_resp->pduSession[0].DRBnGRanList[i].UpParamList[0].teId;
|
||||||
req->mnc_digit_length = RC.nrrrc[ctxt.module_id]->configuration.mnc_digit_length[0];
|
drbs[i].up_ul_tnl_length = 1;
|
||||||
req->nr_cellid = RC.nrrrc[ctxt.module_id]->nr_cellid;
|
|
||||||
|
|
||||||
/*Instruction towards the DU for SRB2 configuration*/
|
|
||||||
req->srbs_to_be_setup = malloc(1*sizeof(f1ap_srb_to_be_setup_t));
|
|
||||||
req->srbs_to_be_setup_length = 1;
|
|
||||||
f1ap_srb_to_be_setup_t *SRBs=req->srbs_to_be_setup;
|
|
||||||
SRBs[0].srb_id = 2;
|
|
||||||
SRBs[0].lcid = 2;
|
|
||||||
|
|
||||||
/*Instruction towards the DU for DRB configuration and tunnel creation*/
|
|
||||||
req->drbs_to_be_setup_length = e1ap_resp->pduSession[0].numDRBSetup;
|
|
||||||
req->drbs_to_be_setup = malloc(1*sizeof(f1ap_drb_to_be_setup_t)*req->drbs_to_be_setup_length);
|
|
||||||
for (int i=0; i < e1ap_resp->pduSession[0].numDRBSetup; i++) {
|
|
||||||
f1ap_drb_to_be_setup_t *DRBs = req->drbs_to_be_setup + i;
|
|
||||||
DRBs[i].drb_id = e1ap_resp->pduSession[0].DRBnGRanList[i].id;
|
|
||||||
DRBs[i].rlc_mode = RLC_MODE_AM;
|
|
||||||
DRBs[i].up_ul_tnl[0].tl_address = e1ap_resp->pduSession[0].DRBnGRanList[i].UpParamList[0].tlAddress;
|
|
||||||
DRBs[i].up_ul_tnl[0].port = RC.nrrrc[ctxt.module_id]->eth_params_s.my_portd;
|
|
||||||
DRBs[i].up_ul_tnl[0].teid = e1ap_resp->pduSession[0].DRBnGRanList[i].UpParamList[0].teId;
|
|
||||||
DRBs[i].up_ul_tnl_length = 1;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
itti_send_msg_to_task (TASK_CU_F1, ctxt.module_id, message_p);
|
/* Instruction towards the DU for SRB2 configuration */
|
||||||
|
int nb_srb = 1;
|
||||||
|
f1ap_srb_to_be_setup_t srbs[nb_srb];
|
||||||
|
srbs[0].srb_id = 2;
|
||||||
|
srbs[0].lcid = 2;
|
||||||
|
|
||||||
|
f1ap_ue_context_modif_req_t ue_context_modif_req = {
|
||||||
|
.gNB_CU_ue_id = 0xffffffff, /* filled by F1 for the moment */
|
||||||
|
.gNB_DU_ue_id = 0xffffffff, /* filled by F1 for the moment */
|
||||||
|
.rnti = UE->rnti,
|
||||||
|
.mcc = rrc->configuration.mcc[0],
|
||||||
|
.mnc = rrc->configuration.mnc[0],
|
||||||
|
.mnc_digit_length = rrc->configuration.mnc_digit_length[0],
|
||||||
|
.nr_cellid = rrc->nr_cellid,
|
||||||
|
.servCellId = 0, /* TODO: correct value? */
|
||||||
|
.srbs_to_be_setup_length = nb_srb,
|
||||||
|
.srbs_to_be_setup = srbs,
|
||||||
|
.drbs_to_be_setup_length = nb_drb,
|
||||||
|
.drbs_to_be_setup = drbs,
|
||||||
|
};
|
||||||
|
rrc->mac_rrc.ue_context_modification_request(&ue_context_modif_req);
|
||||||
}
|
}
|
||||||
|
|
||||||
void rrc_gNB_process_e1_bearer_context_setup_resp(e1ap_bearer_setup_resp_t *resp, instance_t instance) {
|
void rrc_gNB_process_e1_bearer_context_setup_resp(e1ap_bearer_setup_resp_t *resp, instance_t instance) {
|
||||||
@@ -3047,10 +2859,6 @@ void *rrc_gnb_task(void *args_p) {
|
|||||||
rrc_CU_process_ue_context_modification_response(msg_p, instance);
|
rrc_CU_process_ue_context_modification_response(msg_p, instance);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case F1AP_UE_CONTEXT_MODIFICATION_REQ:
|
|
||||||
rrc_DU_process_ue_context_modification_request(msg_p, instance);
|
|
||||||
break;
|
|
||||||
|
|
||||||
case F1AP_UE_CONTEXT_RELEASE_REQ:
|
case F1AP_UE_CONTEXT_RELEASE_REQ:
|
||||||
rrc_CU_process_ue_context_release_request(msg_p);
|
rrc_CU_process_ue_context_release_request(msg_p);
|
||||||
break;
|
break;
|
||||||
|
|||||||
Reference in New Issue
Block a user