Commit 028f0407 authored by Sakthivel Velumani's avatar Sakthivel Velumani

Completed bearer context setup cycle

To be tested: Handling of bearer context setup response and subsequent UE context modifition msg to F1AP task
parent 4481d113
......@@ -121,7 +121,7 @@ typedef struct DRB_nGRAN_to_setup_s {
typedef struct pdu_session_to_setup_s {
long sessionId;
long sessionType;
int32_t sst;
int8_t sst;
long integrityProtectionIndication;
long confidentialityProtectionIndication;
in_addr_t tlAddress;
......
......@@ -573,18 +573,19 @@ int e1apCUCP_send_BEARER_CONTEXT_SETUP_REQUEST(instance_t instance,
ieC6->criticality = E1AP_Criticality_reject;
ieC6->value.present = E1AP_BearerContextSetupRequestIEs__value_PR_System_BearerContextSetupRequest;
ieC6->value.choice.System_BearerContextSetupRequest.present = E1AP_System_BearerContextSetupRequest_PR_nG_RAN_BearerContextSetupRequest;
E1AP_NG_RAN_BearerContextSetupRequest_t *msgNGRAN = calloc(1, sizeof(E1AP_NG_RAN_BearerContextSetupRequest_t));
ieC6->value.choice.System_BearerContextSetupRequest.choice.nG_RAN_BearerContextSetupRequest = (struct E1AP_ProtocolIE_Container *) msgNGRAN;
E1AP_ProtocolIE_Container_4932P19_t *msgNGRAN_list = calloc(1, sizeof(E1AP_ProtocolIE_Container_4932P19_t));
ieC6->value.choice.System_BearerContextSetupRequest.choice.nG_RAN_BearerContextSetupRequest = (struct E1AP_ProtocolIE_Container *) msgNGRAN_list;
asn1cSequenceAdd(msgNGRAN_list->list, E1AP_NG_RAN_BearerContextSetupRequest_t, msgNGRAN);
msgNGRAN->id = E1AP_ProtocolIE_ID_id_PDU_Session_Resource_To_Setup_List;
msgNGRAN->criticality = E1AP_Criticality_reject;
msgNGRAN->value.present = E1AP_NG_RAN_BearerContextSetupRequest__value_PR_PDU_Session_Resource_To_Setup_List;
E1AP_PDU_Session_Resource_To_Setup_List_t *pdu2Setup = &msgNGRAN->value.choice.PDU_Session_Resource_To_Setup_List;
for(pdu_session_to_setup_t *i=bearerCxt->pduSession; i < bearerCxt->pduSession+bearerCxt->numPDUSessions; i++) {
asn1cSequenceAdd(pdu2Setup->list, E1AP_PDU_Session_Resource_To_Setup_Item_t, ieC6_1);
ieC6_1->pDU_Session_ID = i->sessionId;
ieC6_1->pDU_Session_Type = i->sessionType;
INT32_TO_OCTET_STRING(i->sst, &ieC6_1->sNSSAI.sST);
INT8_TO_OCTET_STRING(i->sst, &ieC6_1->sNSSAI.sST);
ieC6_1->securityIndication.integrityProtectionIndication = i->integrityProtectionIndication;
ieC6_1->securityIndication.confidentialityProtectionIndication = i->confidentialityProtectionIndication;
......@@ -636,7 +637,6 @@ int e1apCUCP_send_BEARER_CONTEXT_SETUP_REQUEST(instance_t instance,
ieC6_1_1_1->qoSFlowLevelQoSParameters.nGRANallocationRetentionPriority.pre_emptionCapability = k->pre_emptionCapability;
ieC6_1_1_1->qoSFlowLevelQoSParameters.nGRANallocationRetentionPriority.pre_emptionVulnerability = k->pre_emptionVulnerability;
}
}
}
......@@ -843,7 +843,10 @@ int e1apCUUP_handle_BEARER_CONTEXT_SETUP_REQUEST(instance_t instance,
"ie->criticality != E1AP_Criticality_ignore\n");
AssertFatal(ie->value.present == E1AP_BearerContextSetupRequestIEs__value_PR_PLMN_Identity,
"ie->value.present != E1AP_BearerContextSetupRequestIEs__value_PR_PLMN_Identity\n");
//TODO
PLMNID_TO_MCC_MNC(&ie->value.choice.PLMN_Identity,
bearerCxt->servingPLMNid.mcc,
bearerCxt->servingPLMNid.mnc,
bearerCxt->servingPLMNid.mnc_digit_length);
break;
case E1AP_ProtocolIE_ID_id_ActivityNotificationLevel:
......@@ -854,7 +857,105 @@ int e1apCUUP_handle_BEARER_CONTEXT_SETUP_REQUEST(instance_t instance,
bearerCxt->activityNotificationLevel = ie->value.choice.ActivityNotificationLevel;
break;
// TODO: remaining IE handlers
case E1AP_ProtocolIE_ID_id_System_BearerContextSetupRequest:
AssertFatal(ie->criticality == E1AP_Criticality_reject,
"ie->criticality != E1AP_Criticality_reject\n");
AssertFatal(ie->value.present == E1AP_BearerContextSetupRequestIEs__value_PR_System_BearerContextSetupRequest,
"ie->value.present != E1AP_BearerContextSetupRequestIEs__value_PR_System_BearerContextSetupRequest\n");
AssertFatal(ie->value.choice.System_BearerContextSetupRequest.present ==
E1AP_System_BearerContextSetupRequest_PR_nG_RAN_BearerContextSetupRequest,
"ie->value.choice.System_BearerContextSetupRequest.present !="
"E1AP_System_BearerContextSetupRequest_PR_nG_RAN_BearerContextSetupRequest\n");
AssertFatal(ie->value.choice.System_BearerContextSetupRequest.choice.nG_RAN_BearerContextSetupRequest,
"nG_RAN_BearerContextSetupRequest is NULL\n");
E1AP_ProtocolIE_Container_4932P19_t *msgNGRAN_list = (E1AP_ProtocolIE_Container_4932P19_t *) ie->value.choice.System_BearerContextSetupRequest.choice.nG_RAN_BearerContextSetupRequest;
E1AP_NG_RAN_BearerContextSetupRequest_t *msgNGRAN = msgNGRAN_list->list.array[0];
AssertFatal(msgNGRAN_list->list.count == 1, "nG_RAN_BearerContextSetupRequest supports only 1 count for now\n");
AssertFatal(msgNGRAN->id == E1AP_ProtocolIE_ID_id_PDU_Session_Resource_To_Setup_List,
"msgNGRAN->id (%ld) != E1AP_ProtocolIE_ID_id_PDU_Session_Resource_To_Setup_List\n", msgNGRAN->id);
AssertFatal(msgNGRAN->value.present =
E1AP_NG_RAN_BearerContextSetupRequest__value_PR_PDU_Session_Resource_To_Setup_List,
"msgNGRAN->value.present != E1AP_NG_RAN_BearerContextSetupRequest__value_PR_PDU_Session_Resource_To_Setup_List\n");
E1AP_PDU_Session_Resource_To_Setup_List_t *pdu2SetupList = &msgNGRAN->value.choice.PDU_Session_Resource_To_Setup_List;
for (int i=0; i < pdu2SetupList->list.count; i++) {
pdu_session_to_setup_t *pdu = bearerCxt->pduSession + i;
E1AP_PDU_Session_Resource_To_Setup_Item_t *pdu2Setup = pdu2SetupList->list.array[i];
pdu->sessionId = pdu2Setup->pDU_Session_ID;
pdu->sessionType = pdu2Setup->pDU_Session_Type;
OCTET_STRING_TO_INT8(&pdu2Setup->sNSSAI.sST, pdu->sst);
pdu->integrityProtectionIndication = pdu2Setup->securityIndication.integrityProtectionIndication;
pdu->confidentialityProtectionIndication = pdu2Setup->securityIndication.confidentialityProtectionIndication;
if (pdu2Setup->nG_UL_UP_TNL_Information.choice.gTPTunnel) { // Optional IE
AssertFatal(pdu2Setup->nG_UL_UP_TNL_Information.present = E1AP_UP_TNL_Information_PR_gTPTunnel,
"pdu2Setup->nG_UL_UP_TNL_Information.present != E1AP_UP_TNL_Information_PR_gTPTunnel\n");
BIT_STRING_TO_TRANSPORT_LAYER_ADDRESS_IPv4(&pdu2Setup->nG_UL_UP_TNL_Information.choice.gTPTunnel->transportLayerAddress,
pdu->tlAddress);
OCTET_STRING_TO_INT32(&pdu2Setup->nG_UL_UP_TNL_Information.choice.gTPTunnel->gTP_TEID, pdu->teId);
}
E1AP_DRB_To_Setup_List_NG_RAN_t *drb2SetupList = &pdu2Setup->dRB_To_Setup_List_NG_RAN;
for (int j=0; j < drb2SetupList->list.count; j++) {
DRB_nGRAN_to_setup_t *drb = pdu->DRBnGRanList + j;
E1AP_DRB_To_Setup_Item_NG_RAN_t *drb2Setup = drb2SetupList->list.array[j];
drb->id = drb2Setup->dRB_ID;
drb->defaultDRB = drb2Setup->sDAP_Configuration.defaultDRB;
drb->sDAP_Header_UL = drb2Setup->sDAP_Configuration.sDAP_Header_UL;
drb->sDAP_Header_DL = drb2Setup->sDAP_Configuration.sDAP_Header_DL;
drb->pDCP_SN_Size_UL = drb2Setup->pDCP_Configuration.pDCP_SN_Size_UL;
drb->pDCP_SN_Size_DL = drb2Setup->pDCP_Configuration.pDCP_SN_Size_DL;
if (drb2Setup->pDCP_Configuration.discardTimer) {
drb->discardTimer = *drb2Setup->pDCP_Configuration.discardTimer;
}
if (drb2Setup->pDCP_Configuration.t_ReorderingTimer) {
drb->reorderingTimer = drb2Setup->pDCP_Configuration.t_ReorderingTimer->t_Reordering;
}
drb->rLC_Mode = drb2Setup->pDCP_Configuration.rLC_Mode;
E1AP_Cell_Group_Information_t *cellGroupList = &drb2Setup->cell_Group_Information;
for (int k=0; k < cellGroupList->list.count; k++) {
E1AP_Cell_Group_Information_Item_t *cg2Setup = cellGroupList->list.array[k];
drb->cellGroupList[k].id = cg2Setup->cell_Group_ID;
}
E1AP_QoS_Flow_QoS_Parameter_List_t *qos2SetupList = &drb2Setup->qos_flow_Information_To_Be_Setup;
for (int k=0; k < qos2SetupList->list.count; k++) {
qos_flow_to_setup_t *qos = drb->qosFlows + k;
E1AP_QoS_Flow_QoS_Parameter_Item_t *qos2Setup = qos2SetupList->list.array[k];
qos->id = qos2Setup->qoS_Flow_Identifier;
if (qos2Setup->qoSFlowLevelQoSParameters.qoS_Characteristics.present ==
E1AP_QoS_Characteristics_PR_non_Dynamic_5QI) {
qos->fiveQI_type = non_dynamic;
qos->fiveQI = qos2Setup->qoSFlowLevelQoSParameters.qoS_Characteristics.choice.non_Dynamic_5QI->fiveQI;
} else {
E1AP_Dynamic5QIDescriptor_t *dynamic5QI = qos2Setup->qoSFlowLevelQoSParameters.qoS_Characteristics.choice.dynamic_5QI;
qos->fiveQI_type = dynamic;
qos->qoSPriorityLevel = dynamic5QI->qoSPriorityLevel;
qos->packetDelayBudget = dynamic5QI->packetDelayBudget;
qos->packetError_scalar = dynamic5QI->packetErrorRate.pER_Scalar;
qos->packetError_exponent = dynamic5QI->packetErrorRate.pER_Exponent;
}
qos->priorityLevel = qos2Setup->qoSFlowLevelQoSParameters.nGRANallocationRetentionPriority.priorityLevel;
qos->pre_emptionCapability = qos2Setup->qoSFlowLevelQoSParameters.nGRANallocationRetentionPriority.pre_emptionCapability;
qos->pre_emptionVulnerability = qos2Setup->qoSFlowLevelQoSParameters.nGRANallocationRetentionPriority.pre_emptionVulnerability;
}
}
}
break;
default:
LOG_E(E1AP, "Handle for this IE is not implemented (or) invalid IE detected\n");
......@@ -1251,6 +1352,11 @@ void *E1AP_CUUP_task(void *arg) {
cuxp_task_handle_sctp_data_ind(myInstance, &msg->ittiMsg.sctp_data_ind);
break;
case E1AP_BEARER_CONTEXT_SETUP_RESP:
LOG_I(E1AP, "CUUP Task Received E1AP_BEARER_CONTEXT_SETUP_RESP\n");
e1apCUUP_send_BEARER_CONTEXT_SETUP_RESPONSE(myInstance, &E1AP_BEARER_CONTEXT_SETUP_RESP(msg));
break;
default:
LOG_E(E1AP, "Unknown message received in TASK_CUUP_E1\n");
break;
......
......@@ -3895,7 +3895,7 @@ void fill_DRB_configList(NR_DRB_ToAddModList_t *DRB_configList, pdu_session_to_s
ASN_SEQUENCE_ADD(&sdap_config->mappedQoS_FlowsToAdd->list, qfi);
}
sdap_config->mappedQoS_FlowsToRelease = NULL;
/*
// pdcp_Config
ie->reestablishPDCP = NULL;
ie->recoverPDCP = NULL;
......@@ -3917,23 +3917,22 @@ void fill_DRB_configList(NR_DRB_ToAddModList_t *DRB_configList, pdu_session_to_s
pdcp_config->drb->outOfOrderDelivery = NULL;
pdcp_config->moreThanOneRLC = NULL;
pdcp_config->t_Reordering = calloc(1, sizeof(*drb->pdcp_config->t_Reordering));
pdcp_config->t_Reordering = calloc(1, sizeof(*pdcp_config->t_Reordering));
*pdcp_config->t_Reordering = drb->reorderingTimer;
pdcp_config->ext1 = NULL;
if (drb->integrityProtectionIndication == 0 || // Required
drb->integrityProtectionIndication == 1) { // Preferred
if (pdu->integrityProtectionIndication == 0 || // Required
pdu->integrityProtectionIndication == 1) { // Preferred
pdcp_config->drb->integrityProtection = calloc(1, sizeof(*pdcp_config->drb->integrityProtection));
*pdcp_config->drb->integrityProtection = NR_PDCP_Config__drb__integrityProtection_enabled;
}
if (drb->confidentialityProtectionIndication == 0 || // Required
drb->confidentialityProtectionIndication == 1) { // Preferred
if (pdu->confidentialityProtectionIndication == 0 || // Required
pdu->confidentialityProtectionIndication == 1) { // Preferred
pdcp_config->ext1 = calloc(1, sizeof(*pdcp_config->ext1));
pdcp_config->ext1->cipheringDisabled = calloc(1, sizeof(*pdcp_config->ext1->cipheringDisabled));
*pdcp_config->ext1->cipheringDisabled = NR_PDCP_Config__ext1__cipheringDisabled_true;
}
*/
}
}
......@@ -3942,7 +3941,7 @@ int rrc_gNB_process_e1_bearer_context_setup_req(e1ap_bearer_setup_req_t *req, in
gtpv1u_gnb_create_tunnel_req_t create_tunnel_req={0};
gtpv1u_gnb_create_tunnel_resp_t create_tunnel_resp={0};
NR_DRB_ToAddModList_t *DRB_configList;
NR_DRB_ToAddModList_t DRB_configList;
for (int i=0; i < req->numPDUSessions; i++) {
pdu_session_to_setup_t *pdu = &req->pduSession[i];
create_tunnel_req.pdusession_id[i] = pdu->sessionId;
......@@ -3951,28 +3950,121 @@ int rrc_gNB_process_e1_bearer_context_setup_req(e1ap_bearer_setup_req_t *req, in
&pdu->tlAddress,
sizeof(pdu->tlAddress));
create_tunnel_req.outgoing_teid[i] = pdu->teId;
fill_DRB_configList(DRB_configList, pdu);
fill_DRB_configList(&DRB_configList, pdu);
}
create_tunnel_req.num_tunnels = req->numPDUSessions;
create_tunnel_req.ue_id = (req->gNB_cu_cp_ue_id & 0xFFFF);
create_tunnel_req.ue_id = (req->gNB_cu_cp_ue_id & 0xFFFF);
int ret = gtpv1u_create_ngu_tunnel(
instance,
&create_tunnel_req,
&create_tunnel_resp);
if (ret != 0) {
LOG_E(NR_RRC,"rrc_gNB_process_NGAP_PDUSESSION_SETUP_REQ : gtpv1u_create_ngu_tunnel failed,start to release UE id %ld\n",
create_tunnel_req.ue_id);
return ret;
}
uint8_t *kRRCenc = NULL;
uint8_t *kRRCint = NULL;
/*
nr_derive_key_rrc_enc(cipheringAlgorithm,
encryptionKey,
&kRRCenc);
// Configure DRBs
uint8_t *kUPenc = NULL;
uint8_t *kUPint = NULL;
nr_derive_key_rrc_int(integrityProtectionAlgorithm,
integrityProtectionKey,
&kRRCint);
*/
return 0;
nr_derive_key_rrc_enc(req->cipheringAlgorithm,
(uint8_t *)req->encryptionKey,
&kUPenc);
nr_derive_key_rrc_int(req->integrityProtectionAlgorithm,
(uint8_t *)req->integrityProtectionKey,
&kUPint);
nr_pdcp_add_drbs(false,
create_tunnel_req.ue_id,
&DRB_configList,
(req->integrityProtectionAlgorithm << 4) | req->cipheringAlgorithm,
kUPenc,
kUPint,
NULL);
MessageDef *message_p;
message_p = itti_alloc_new_message (TASK_RRC_GNB, instance, E1AP_BEARER_CONTEXT_SETUP_RESP);
e1ap_bearer_setup_resp_t *resp = &E1AP_BEARER_CONTEXT_SETUP_RESP(message_p);
resp->gNB_cu_cp_ue_id = req->gNB_cu_cp_ue_id;
resp->numPDUSessions = req->numPDUSessions;
for (int i=0; i < req->numPDUSessions; i++) {
pdu_session_setup_t *pduSetup = resp->pduSession + i;
pdu_session_to_setup_t *pdu2Setup = req->pduSession + i;
pduSetup->id = pdu2Setup->sessionId;
memcpy(&pduSetup->tlAddress, &pdu2Setup->tlAddress, sizeof(in_addr_t));
pduSetup->teId = pdu2Setup->teId;
pduSetup->numDRBSetup = pdu2Setup->numDRB2Setup;
for (int j=0; j < pdu2Setup->numDRB2Setup; j++) {
DRB_nGRAN_setup_t *drbSetup = pduSetup->DRBnGRanList + j;
DRB_nGRAN_to_setup_t *drb2Setup = pdu2Setup->DRBnGRanList + j;
drbSetup->id = drb2Setup->id;
drbSetup->numUpParam = 0;
drbSetup->numQosFlowSetup = drb2Setup->numQosFlow2Setup;
for (int k=0; k < drbSetup->numQosFlowSetup; k++) {
drbSetup->qosFlows[k].id = drb2Setup->qosFlows[k].id;
}
}
}
// At this point we don't have a way to know the DRBs that failed to setup
// We assume all DRBs to setup have are setup successfully so we always send successful outcome in response
// TODO: Modify nr_pdcp_add_drbs() to return DRB list that failed to setup to support E1AP
itti_send_msg_to_task(TASK_CUUP_E1, instance, message_p);
return ret;
}
void rrc_gNB_process_e1_bearer_context_setup_resp(e1ap_bearer_setup_resp_t *resp, instance_t instance) {
// Find the UE context from UE ID and send ITTI message to F1AP to send UE context modification message to DU
uint16_t ue_initial_id = 0; // Making an invalid UE initial ID
rrc_gNB_ue_context_t *ue_context_p = rrc_gNB_get_ue_context_from_ngap_ids(instance, ue_initial_id, resp->gNB_cu_cp_ue_id);
protocol_ctxt_t ctxt = {0};
PROTOCOL_CTXT_SET_BY_MODULE_ID(&ctxt, 0, GNB_FLAG_YES, ue_context_p->ue_context.rnti, 0, 0, 0);
/*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*/
// TODO: code repetition. very bad. And so many hard codings
MessageDef *message_p;
message_p = itti_alloc_new_message (TASK_RRC_GNB, 0, F1AP_UE_CONTEXT_MODIFICATION_REQ);
f1ap_ue_context_setup_t *req=&F1AP_UE_CONTEXT_MODIFICATION_REQ (message_p);
req->rnti = ue_context_p->ue_context.rnti;
req->mcc = RC.nrrrc[ctxt.module_id]->configuration.mcc[0];
req->mnc = RC.nrrrc[ctxt.module_id]->configuration.mnc[0];
req->mnc_digit_length = RC.nrrrc[ctxt.module_id]->configuration.mnc_digit_length[0];
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 = malloc(1*sizeof(f1ap_drb_to_be_setup_t));
req->drbs_to_be_setup_length = 1;
f1ap_drb_to_be_setup_t *DRBs=req->drbs_to_be_setup;
LOG_D(RRC, "Length of DRB list:%d \n", req->drbs_to_be_setup_length);
DRBs[0].drb_id = 1;
DRBs[0].rlc_mode = RLC_MODE_AM;
DRBs[0].up_ul_tnl[0].tl_address = inet_addr(RC.nrrrc[ctxt.module_id]->eth_params_s.my_addr);
DRBs[0].up_ul_tnl[0].port=RC.nrrrc[ctxt.module_id]->eth_params_s.my_portd;
DRBs[0].up_ul_tnl_length = 1;
DRBs[0].up_dl_tnl[0].tl_address = inet_addr(RC.nrrrc[ctxt.module_id]->eth_params_s.remote_addr);
DRBs[0].up_dl_tnl[0].port=RC.nrrrc[ctxt.module_id]->eth_params_s.remote_portd;
DRBs[0].up_dl_tnl_length = 1;
itti_send_msg_to_task (TASK_CU_F1, ctxt.module_id, message_p);
}
///---------------------------------------------------------------------------------------------------------------///
......@@ -4143,6 +4235,11 @@ void *rrc_gnb_task(void *args_p) {
rrc_gNB_process_e1_bearer_context_setup_req(&E1AP_BEARER_CONTEXT_SETUP_REQ(msg_p), instance);
break;
case E1AP_BEARER_CONTEXT_SETUP_RESP:
LOG_I(NR_RRC, "Received E1AP_BEARER_CONTEXT_SETUP_RESP for instance %d\n", (int)instance);
rrc_gNB_process_e1_bearer_context_setup_resp(&E1AP_BEARER_CONTEXT_SETUP_RESP(msg_p), instance);
break;
default:
LOG_E(NR_RRC, "[gNB %ld] Received unexpected message %s\n", instance, msg_name_p);
break;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment