Commit bc73585d authored by Remi Hardy's avatar Remi Hardy
Browse files

Merge branch 'integration_2020_wk39' into 'develop', comprising :

MR 896 : Nsa remove band hardcodings  
Removes hardcodings of EUTRA and NR bands in UE_Capability_Enquiry and NR_UE Capability_Enquiry messages, providing them from the eNB config file and gNB over X2 respectively. Moreover, the SSB Absolute frequency of the gNB is now provided by the eNB configuration file (instead of being hardcoded at rrc_eNB.c)  

MR903 : pusch ta update  
Update of PUSCH Timing advance  

MR 900 : improve x2/rrc for ENDC  
This MR introduces several enhancements in X2AP and RRC to deal with ENDC. 
The main goal is to deal with UE's on/off and with various errors.
Includes :
- DC prep and DC overall X2 timers
- X2 messages for UE release and DC timers' timeout
parents 5372a347 f69824c9
......@@ -305,7 +305,9 @@ void x2ap_eNB_handle_register_eNB(instance_t instance,
x2ap_id_manager_init(&new_instance->id_manager);
x2ap_timers_init(&new_instance->timers,
x2ap_register_eNB->t_reloc_prep,
x2ap_register_eNB->tx2_reloc_overall);
x2ap_register_eNB->tx2_reloc_overall,
x2ap_register_eNB->t_dc_prep,
x2ap_register_eNB->t_dc_overall);
for (int i = 0; i< x2ap_register_eNB->num_cc; i++) {
new_instance->eutra_band[i] = x2ap_register_eNB->eutra_band[i];
......@@ -476,7 +478,10 @@ void x2ap_eNB_handle_sgNB_add_req(instance_t instance,
}
/* id_source is ue_id, id_target is unknown yet */
x2ap_set_ids(id_manager, ue_id, x2ap_ENDC_sgnb_addition_req->rnti, ue_id, -1);
x2ap_id_set_state(id_manager, ue_id, X2ID_STATE_NSA_PREPARE);
x2ap_id_set_state(id_manager, ue_id, X2ID_STATE_NSA_ENB_PREPARE);
x2ap_set_dc_prep_timer(id_manager, ue_id,
x2ap_timer_get_tti(&instance_p->timers));
x2ap_id_set_target(id_manager, ue_id, x2ap_eNB_data);
x2ap_eNB_generate_ENDC_x2_SgNB_addition_request(instance_p, x2ap_ENDC_sgnb_addition_req,
x2ap_eNB_data, ue_id);
......@@ -498,9 +503,6 @@ void x2ap_gNB_trigger_sgNB_add_req_ack(instance_t instance,
x2ap_eNB_instance_t *instance_p;
x2ap_eNB_data_t *target;
int ue_id;
/*int source_assoc_id = x2ap_ENDC_sgnb_addition_req_ACK->source_assoc_id;
int id_source;
int id_target;*/
instance_p = x2ap_eNB_get_instance(instance);
DevAssert(instance_p != NULL);
......@@ -514,22 +516,15 @@ void x2ap_gNB_trigger_sgNB_add_req_ack(instance_t instance,
X2AP_ERROR("could not allocate a new X2AP UE ID\n");
exit(1);
}
/* id_source is ue_id, id_target is unknown yet */
x2ap_set_ids(id_manager, ue_id, x2ap_ENDC_sgnb_addition_req_ACK->rnti, ue_id,
x2ap_ENDC_sgnb_addition_req_ACK->MeNB_ue_x2_id);
x2ap_id_set_state(id_manager, ue_id, X2ID_STATE_SOURCE_OVERALL);
/*target = x2ap_get_eNB(NULL, source_assoc_id, 0);
DevAssert(target != NULL);*/
// rnti is a new information, save it
/*ue_id = x2ap_handover_req_ack->x2_id_target;
id_source = x2ap_id_get_id_source(&instance_p->id_manager, ue_id);
id_target = ue_id;
x2ap_set_ids(&instance_p->id_manager, ue_id, x2ap_handover_req_ack->rnti, id_source, id_target);*/
/* id_Source is MeNB_ue_x2_id, id_target is rnti (rnti is SgNB_ue_x2_id) */
x2ap_set_ids(id_manager, ue_id,
x2ap_ENDC_sgnb_addition_req_ACK->SgNB_ue_x2_id,
x2ap_ENDC_sgnb_addition_req_ACK->MeNB_ue_x2_id,
x2ap_ENDC_sgnb_addition_req_ACK->SgNB_ue_x2_id);
x2ap_id_set_state(id_manager, ue_id, X2ID_STATE_NSA_GNB_OVERALL);
x2ap_set_dc_overall_timer(id_manager, ue_id,
x2ap_timer_get_tti(&instance_p->timers));
x2ap_id_set_target(id_manager, ue_id, target);
x2ap_gNB_generate_ENDC_x2_SgNB_addition_request_ACK(instance_p, target,
x2ap_ENDC_sgnb_addition_req_ACK, ue_id);
......@@ -540,27 +535,24 @@ void x2ap_gNB_trigger_sgNB_add_req_ack(instance_t instance,
* @param : IN instance, IN x2ap_reconf_complete
**/
static
void x2ap_eNB_trigger_sgnb_reconfiguration_complete(instance_t instance,
x2ap_ENDC_reconf_complete_t *x2ap_reconf_complete)
void x2ap_eNB_trigger_sgnb_reconfiguration_complete(instance_t instance,
x2ap_ENDC_reconf_complete_t *x2ap_reconf_complete)
{
x2ap_eNB_instance_t *instance_p = NULL;
x2ap_eNB_data_t *target = NULL;
int id_source = -1;
int id_target = -1;
LTE_PhysCellId_t target_pci;
x2ap_eNB_instance_t *instance_p;
x2ap_eNB_data_t *target;
int id_source;
int id_target;
instance_p = x2ap_eNB_get_instance(instance);
DevAssert(instance_p != NULL);
DevAssert(x2ap_reconf_complete != NULL);
target_pci = x2ap_reconf_complete->target_physCellId;
target = x2ap_is_eNB_pci_in_list(target_pci);
target = x2ap_get_eNB(NULL,x2ap_reconf_complete->gnb_x2_assoc_id, 0);
DevAssert(target != NULL);
id_source = x2ap_reconf_complete->MeNB_ue_x2_id;
id_target = x2ap_reconf_complete->SgNB_ue_x2_id;
x2ap_eNB_generate_ENDC_x2_SgNB_reconfiguration_complete(instance_p, target, id_source, id_target);
}
......@@ -589,6 +581,34 @@ void x2ap_eNB_ue_context_release(instance_t instance,
x2ap_release_id(&instance_p->id_manager, ue_id);
}
static
void x2ap_eNB_handle_sgNB_release_request(instance_t instance,
x2ap_ENDC_sgnb_release_request_t *x2ap_release_req)
{
x2ap_eNB_instance_t *instance_p;
x2ap_eNB_data_t *target;
instance_p = x2ap_eNB_get_instance(instance);
DevAssert(instance_p != NULL);
DevAssert(x2ap_release_req != NULL);
if (x2ap_release_req->rnti == -1 ||
x2ap_release_req->assoc_id == -1) {
X2AP_WARN("x2ap_eNB_handle_sgNB_release_request: bad rnti or assoc_id, do not send release request to gNB\n");
return;
}
target = x2ap_get_eNB(NULL, x2ap_release_req->assoc_id, 0);
DevAssert(target != NULL);
/* id_source is not used by oai's gNB so it's not big deal. For
* interoperability with other gNBs things may need to be refined.
*/
x2ap_eNB_generate_ENDC_x2_SgNB_release_request(instance_p, target,
0, x2ap_release_req->rnti,
x2ap_release_req->cause);
}
void *x2ap_task(void *arg) {
MessageDef *received_msg = NULL;
int result;
......@@ -640,10 +660,16 @@ void *x2ap_task(void *arg) {
LOG_I(X2AP, "Received elements for X2AP_ENDC_SGNB_ADDITION_REQ_ACK \n");
break;
case X2AP_ENDC_SGNB_RECONF_COMPLETE:
x2ap_eNB_trigger_sgnb_reconfiguration_complete(ITTI_MESSAGE_GET_INSTANCE(received_msg),
&X2AP_ENDC_SGNB_RECONF_COMPLETE(received_msg));
break;
case X2AP_ENDC_SGNB_RECONF_COMPLETE:
x2ap_eNB_trigger_sgnb_reconfiguration_complete(ITTI_MESSAGE_GET_INSTANCE(received_msg),
&X2AP_ENDC_SGNB_RECONF_COMPLETE(received_msg));
break;
case X2AP_ENDC_SGNB_RELEASE_REQUEST:
x2ap_eNB_handle_sgNB_release_request(ITTI_MESSAGE_GET_INSTANCE(received_msg),
&X2AP_ENDC_SGNB_RELEASE_REQUEST(received_msg));
break;
case SCTP_INIT_MSG_MULTI_CNF:
x2ap_eNB_handle_sctp_init_msg_multi_cnf(ITTI_MESSAGE_GET_INSTANCE(received_msg),
&received_msg->ittiMsg.sctp_init_msg_multi_cnf);
......
......@@ -69,6 +69,14 @@ static int x2ap_eNB_decode_initiating_message(X2AP_X2AP_PDU_t *pdu)
X2AP_INFO("X2AP_ProcedureCode_id_sgNBReconfigurationCompletion message!\n");
break;
case X2AP_ProcedureCode_id_meNBinitiatedSgNBRelease:
X2AP_INFO("X2AP_ProcedureCode_id_meNBinitiatedSgNBRelease message!\n");
break;
case X2AP_ProcedureCode_id_sgNBinitiatedSgNBRelease:
X2AP_INFO("X2AP_ProcedureCode_id_sgNBinitiatedSgNBRelease message!\n");
break;
default:
X2AP_ERROR("Unknown procedure ID (%d) for initiating message\n",
(int)pdu->choice.initiatingMessage.procedureCode);
......@@ -103,6 +111,10 @@ static int x2ap_eNB_decode_successful_outcome(X2AP_X2AP_PDU_t *pdu)
X2AP_INFO("x2ap_eNB_decode_successfuloutcome_message!\n");
break;
case X2AP_ProcedureCode_id_meNBinitiatedSgNBRelease:
X2AP_INFO("meNBinitiatedSgNBRelease successful outcome!\n");
break;
default:
X2AP_ERROR("Unknown procedure ID (%d) for successfull outcome message\n",
(int)pdu->choice.successfulOutcome.procedureCode);
......
......@@ -119,6 +119,8 @@ typedef struct x2ap_eNB_data_s {
/* Nid cells */
uint32_t Nid_cell[MAX_NUM_CCs];
int num_cc;
/*Frequency band of NR neighbor cell supporting ENDC NSA */
uint32_t servedNrCell_band[MAX_NUM_CCs];
/* Only meaningfull in virtual mode */
struct x2ap_eNB_instance_s *x2ap_eNB_instance;
......
......@@ -1317,7 +1317,7 @@ MCC_MNC_TO_PLMNID(instance_p->mcc, instance_p->mnc, instance_p->mnc_digit_length
freq_band = calloc(1, sizeof(X2AP_FreqBandNrItem_t));
if (freq_band == NULL)
exit(1);
freq_band->freqBandIndicatorNr = 1; /* TODO: put correct value */
freq_band->freqBandIndicatorNr = instance_p->eutra_band[0];
SULFreqBandItem = calloc(1, sizeof(X2AP_SupportedSULFreqBandItem_t));
SULFreqBandItem->freqBandIndicatorNr=80; /* TODO: put correct value */
......@@ -1668,8 +1668,6 @@ int x2ap_gNB_generate_ENDC_x2_SgNB_addition_request_ACK( x2ap_eNB_instance_t *in
uint32_t len;
int ret = 0;
int MeNB_UE_X2AP_id = x2ap_sgnb_addition_req_ACK->MeNB_ue_x2_id;
int SgNB_UE_X2AP_id = ue_id;
int e_rabs_admitted_tobeadded = x2ap_sgnb_addition_req_ACK->nb_e_rabs_admitted_tobeadded;
long int pDCPatSgNB = X2AP_EN_DC_ResourceConfiguration__pDCPatSgNB_present;
long int mCGresources = X2AP_EN_DC_ResourceConfiguration__mCGresources_not_present;
......@@ -1694,7 +1692,7 @@ int x2ap_gNB_generate_ENDC_x2_SgNB_addition_request_ACK( x2ap_eNB_instance_t *in
ie->id = X2AP_ProtocolIE_ID_id_MeNB_UE_X2AP_ID;
ie->criticality= X2AP_Criticality_reject;
ie->value.present = X2AP_SgNBAdditionRequestAcknowledge_IEs__value_PR_UE_X2AP_ID;
ie->value.choice.UE_X2AP_ID = MeNB_UE_X2AP_id; //x2ap_id_get_id_source(&instance_p->id_manager, ue_id);
ie->value.choice.UE_X2AP_ID = x2ap_id_get_id_source(&instance_p->id_manager, ue_id);
ASN_SEQUENCE_ADD(&out->protocolIEs.list, ie);
// SgNB_UE_X2AP_id
......@@ -1702,7 +1700,7 @@ int x2ap_gNB_generate_ENDC_x2_SgNB_addition_request_ACK( x2ap_eNB_instance_t *in
ie->id = X2AP_ProtocolIE_ID_id_SgNB_UE_X2AP_ID;
ie->criticality= X2AP_Criticality_reject;
ie->value.present = X2AP_SgNBAdditionRequestAcknowledge_IEs__value_PR_SgNB_UE_X2AP_ID;
ie->value.choice.UE_X2AP_ID = SgNB_UE_X2AP_id; //x2ap_id_get_id_source(&instance_p->id_manager, ue_id);
ie->value.choice.UE_X2AP_ID = x2ap_id_get_id_target(&instance_p->id_manager, ue_id);
ASN_SEQUENCE_ADD(&out->protocolIEs.list, ie);
ie = (X2AP_SgNBAdditionRequestAcknowledge_IEs_t *)calloc(1, sizeof(X2AP_SgNBAdditionRequestAcknowledge_IEs_t));
......@@ -1792,7 +1790,7 @@ int x2ap_eNB_generate_ENDC_x2_SgNB_reconfiguration_complete(
ie->id = X2AP_ProtocolIE_ID_id_MeNB_UE_X2AP_ID;
ie->criticality= X2AP_Criticality_reject;
ie->value.present = X2AP_SgNBReconfigurationComplete_IEs__value_PR_UE_X2AP_ID;
ie->value.choice.UE_X2AP_ID = ue_id; //x2ap_id_get_id_source(&instance_p->id_manager, ue_id);
ie->value.choice.UE_X2AP_ID = x2ap_id_get_id_source(&instance_p->id_manager, ue_id);
ASN_SEQUENCE_ADD(&out->protocolIEs.list, ie);
ie = (X2AP_SgNBReconfigurationComplete_IEs_t *)calloc(1, sizeof(X2AP_SgNBReconfigurationComplete_IEs_t));
......@@ -1821,3 +1819,226 @@ int x2ap_eNB_generate_ENDC_x2_SgNB_reconfiguration_complete(
return ret;
}
int x2ap_eNB_generate_ENDC_x2_SgNB_release_request(
x2ap_eNB_instance_t *instance_p, x2ap_eNB_data_t *x2ap_eNB_data_p,
int x2_id_source, int x2_id_target, x2ap_cause_t cause)
{
X2AP_X2AP_PDU_t pdu;
X2AP_SgNBReleaseRequest_t *out;
X2AP_SgNBReleaseRequest_IEs_t *ie;
uint8_t *buffer;
uint32_t len;
int ret = 0;
DevAssert(instance_p != NULL);
DevAssert(x2ap_eNB_data_p != NULL);
memset(&pdu, 0, sizeof(pdu));
pdu.present = X2AP_X2AP_PDU_PR_initiatingMessage;
pdu.choice.initiatingMessage.procedureCode = X2AP_ProcedureCode_id_meNBinitiatedSgNBRelease;
pdu.choice.initiatingMessage.criticality = X2AP_Criticality_ignore;
pdu.choice.initiatingMessage.value.present = X2AP_InitiatingMessage__value_PR_SgNBReleaseRequest;
out = &pdu.choice.initiatingMessage.value.choice.SgNBReleaseRequest;
ie = (X2AP_SgNBReleaseRequest_IEs_t *)calloc(1, sizeof(X2AP_SgNBReleaseRequest_IEs_t));
ie->id = X2AP_ProtocolIE_ID_id_MeNB_UE_X2AP_ID;
ie->criticality= X2AP_Criticality_reject;
ie->value.present = X2AP_SgNBReleaseRequest_IEs__value_PR_UE_X2AP_ID;
ie->value.choice.UE_X2AP_ID = x2_id_source;
ASN_SEQUENCE_ADD(&out->protocolIEs.list, ie);
if (x2_id_target != -1) {
ie = (X2AP_SgNBReleaseRequest_IEs_t *)calloc(1, sizeof(X2AP_SgNBReleaseRequest_IEs_t));
ie->id = X2AP_ProtocolIE_ID_id_SgNB_UE_X2AP_ID;
ie->criticality= X2AP_Criticality_reject;
ie->value.present = X2AP_SgNBReleaseRequest_IEs__value_PR_SgNB_UE_X2AP_ID;
ie->value.choice.SgNB_UE_X2AP_ID = x2_id_target;
ASN_SEQUENCE_ADD(&out->protocolIEs.list, ie);
}
ie = (X2AP_SgNBReleaseRequest_IEs_t *)calloc(1, sizeof(X2AP_SgNBReleaseRequest_IEs_t));
ie->id = X2AP_ProtocolIE_ID_id_Cause;
ie->criticality= X2AP_Criticality_ignore;
ie->value.present = X2AP_SgNBReleaseRequest_IEs__value_PR_Cause;
switch (cause) {
case X2AP_CAUSE_T_DC_PREP_TIMEOUT:
ie->value.choice.Cause.present = X2AP_Cause_PR_radioNetwork;
ie->value.choice.Cause.choice.radioNetwork = X2AP_CauseRadioNetwork_tDCprep_expiry;
break;
case X2AP_CAUSE_RADIO_CONNECTION_WITH_UE_LOST:
ie->value.choice.Cause.present = X2AP_Cause_PR_radioNetwork;
ie->value.choice.Cause.choice.radioNetwork = X2AP_CauseRadioNetwork_radio_connection_with_UE_lost;
break;
default:
X2AP_ERROR("%s: unhandled cause %d\n", __FUNCTION__, cause);
exit(1);
}
ASN_SEQUENCE_ADD(&out->protocolIEs.list, ie);
if (x2ap_eNB_encode_pdu(&pdu, &buffer, &len) < 0) {
X2AP_ERROR("Failed to encode ENDC X2 SgNB_release_request message\n");
return -1;
}
x2ap_eNB_itti_send_sctp_data_req(instance_p->instance, x2ap_eNB_data_p->assoc_id, buffer, len, 0);
return ret;
}
int x2ap_gNB_generate_ENDC_x2_SgNB_release_request_acknowledge(
x2ap_eNB_instance_t *instance_p, x2ap_eNB_data_t *x2ap_eNB_data_p,
int menb_ue_x2ap_id, int sgnb_ue_x2ap_id)
{
X2AP_X2AP_PDU_t pdu;
X2AP_SgNBReleaseRequestAcknowledge_t *out;
X2AP_SgNBReleaseRequestAcknowledge_IEs_t *ie;
uint8_t *buffer;
uint32_t len;
int ret = 0;
DevAssert(instance_p != NULL);
DevAssert(x2ap_eNB_data_p != NULL);
x2ap_eNB_data_p->state = X2AP_ENB_STATE_WAITING;
memset(&pdu, 0, sizeof(pdu));
pdu.present = X2AP_X2AP_PDU_PR_successfulOutcome;
pdu.choice.successfulOutcome.procedureCode = X2AP_ProcedureCode_id_meNBinitiatedSgNBRelease;
pdu.choice.successfulOutcome.criticality = X2AP_Criticality_ignore;
pdu.choice.successfulOutcome.value.present = X2AP_SuccessfulOutcome__value_PR_SgNBReleaseRequestAcknowledge;
out = &pdu.choice.successfulOutcome.value.choice.SgNBReleaseRequestAcknowledge;
ie = (X2AP_SgNBReleaseRequestAcknowledge_IEs_t *)calloc(1, sizeof(X2AP_SgNBReleaseRequestAcknowledge_IEs_t));
ie->id = X2AP_ProtocolIE_ID_id_MeNB_UE_X2AP_ID;
ie->criticality= X2AP_Criticality_ignore;
ie->value.present = X2AP_SgNBReleaseRequestAcknowledge_IEs__value_PR_UE_X2AP_ID;
ie->value.choice.UE_X2AP_ID = menb_ue_x2ap_id;
ASN_SEQUENCE_ADD(&out->protocolIEs.list, ie);
ie = (X2AP_SgNBReleaseRequestAcknowledge_IEs_t *)calloc(1, sizeof(X2AP_SgNBReleaseRequestAcknowledge_IEs_t));
ie->id = X2AP_ProtocolIE_ID_id_SgNB_UE_X2AP_ID;
ie->criticality= X2AP_Criticality_ignore;
ie->value.present = X2AP_SgNBReleaseRequestAcknowledge_IEs__value_PR_SgNB_UE_X2AP_ID;
ie->value.choice.SgNB_UE_X2AP_ID = sgnb_ue_x2ap_id;
ASN_SEQUENCE_ADD(&out->protocolIEs.list, ie);
if (x2ap_eNB_encode_pdu(&pdu, &buffer, &len) < 0) {
X2AP_ERROR("Failed to encode ENDC X2 SgNB Release Request Acknowledge\n");
return -1;
}
x2ap_eNB_itti_send_sctp_data_req(instance_p->instance, x2ap_eNB_data_p->assoc_id, buffer, len, 0);
return ret;
}
int x2ap_eNB_generate_ENDC_x2_SgNB_release_required(
x2ap_eNB_instance_t *instance_p, x2ap_eNB_data_t *x2ap_eNB_data_p,
int x2_id_source, int x2_id_target, x2ap_cause_t cause)
{
X2AP_X2AP_PDU_t pdu;
X2AP_SgNBReleaseRequired_t *out;
X2AP_SgNBReleaseRequired_IEs_t *ie;
uint8_t *buffer;
uint32_t len;
int ret = 0;
DevAssert(instance_p != NULL);
DevAssert(x2ap_eNB_data_p != NULL);
/* Prepare the X2AP message to encode */
memset(&pdu, 0, sizeof(pdu));
pdu.present = X2AP_X2AP_PDU_PR_initiatingMessage;
pdu.choice.initiatingMessage.procedureCode = X2AP_ProcedureCode_id_sgNBinitiatedSgNBRelease;
pdu.choice.initiatingMessage.criticality = X2AP_Criticality_reject;
pdu.choice.initiatingMessage.value.present = X2AP_InitiatingMessage__value_PR_SgNBReleaseRequired;
out = &pdu.choice.initiatingMessage.value.choice.SgNBReleaseRequired;
ie = (X2AP_SgNBReleaseRequired_IEs_t *)calloc(1, sizeof(X2AP_SgNBReleaseRequired_IEs_t));
ie->id = X2AP_ProtocolIE_ID_id_MeNB_UE_X2AP_ID;
ie->criticality= X2AP_Criticality_reject;
ie->value.present = X2AP_SgNBReleaseRequired_IEs__value_PR_UE_X2AP_ID;
ie->value.choice.UE_X2AP_ID = x2_id_source;
ASN_SEQUENCE_ADD(&out->protocolIEs.list, ie);
ie = (X2AP_SgNBReleaseRequired_IEs_t *)calloc(1, sizeof(X2AP_SgNBReleaseRequired_IEs_t));
ie->id = X2AP_ProtocolIE_ID_id_SgNB_UE_X2AP_ID;
ie->criticality= X2AP_Criticality_reject;
ie->value.present = X2AP_SgNBReleaseRequired_IEs__value_PR_SgNB_UE_X2AP_ID;
ie->value.choice.SgNB_UE_X2AP_ID = x2_id_target;
ASN_SEQUENCE_ADD(&out->protocolIEs.list, ie);
ie = (X2AP_SgNBReleaseRequired_IEs_t *)calloc(1, sizeof(X2AP_SgNBReleaseRequired_IEs_t));
ie->id = X2AP_ProtocolIE_ID_id_Cause;
ie->criticality= X2AP_Criticality_ignore;
ie->value.present = X2AP_SgNBReleaseRequired_IEs__value_PR_Cause;
switch (cause) {
case X2AP_CAUSE_T_DC_OVERALL_TIMEOUT:
ie->value.choice.Cause.present = X2AP_Cause_PR_radioNetwork;
ie->value.choice.Cause.choice.radioNetwork = X2AP_CauseRadioNetwork_tDCoverall_expiry;
break;
default:
X2AP_ERROR("%s: unhandled cause %d\n", __FUNCTION__, cause);
exit(1);
}
ASN_SEQUENCE_ADD(&out->protocolIEs.list, ie);
if (x2ap_eNB_encode_pdu(&pdu, &buffer, &len) < 0) {
X2AP_ERROR("Failed to encode ENDC X2 SgNB_release_request message\n");
return -1;
}
x2ap_eNB_itti_send_sctp_data_req(instance_p->instance, x2ap_eNB_data_p->assoc_id, buffer, len, 0);
return ret;
}
int x2ap_gNB_generate_ENDC_x2_SgNB_release_confirm(
x2ap_eNB_instance_t *instance_p, x2ap_eNB_data_t *x2ap_eNB_data_p,
int menb_ue_x2ap_id, int sgnb_ue_x2ap_id)
{
X2AP_X2AP_PDU_t pdu;
X2AP_SgNBReleaseConfirm_t *out;
X2AP_SgNBReleaseConfirm_IEs_t *ie;
uint8_t *buffer;
uint32_t len;
int ret = 0;
DevAssert(instance_p != NULL);
DevAssert(x2ap_eNB_data_p != NULL);
memset(&pdu, 0, sizeof(pdu));
pdu.present = X2AP_X2AP_PDU_PR_successfulOutcome;
pdu.choice.successfulOutcome.procedureCode = X2AP_ProcedureCode_id_sgNBinitiatedSgNBRelease;
pdu.choice.successfulOutcome.criticality = X2AP_Criticality_reject;
pdu.choice.successfulOutcome.value.present = X2AP_SuccessfulOutcome__value_PR_SgNBReleaseConfirm;
out = &pdu.choice.successfulOutcome.value.choice.SgNBReleaseConfirm;
ie = (X2AP_SgNBReleaseConfirm_IEs_t *)calloc(1, sizeof(X2AP_SgNBReleaseConfirm_IEs_t));
ie->id = X2AP_ProtocolIE_ID_id_MeNB_UE_X2AP_ID;
ie->criticality= X2AP_Criticality_ignore;
ie->value.present = X2AP_SgNBReleaseConfirm_IEs__value_PR_UE_X2AP_ID;
ie->value.choice.UE_X2AP_ID = menb_ue_x2ap_id;
ASN_SEQUENCE_ADD(&out->protocolIEs.list, ie);
ie = (X2AP_SgNBReleaseConfirm_IEs_t *)calloc(1, sizeof(X2AP_SgNBReleaseConfirm_IEs_t));
ie->id = X2AP_ProtocolIE_ID_id_SgNB_UE_X2AP_ID;
ie->criticality= X2AP_Criticality_ignore;
ie->value.present = X2AP_SgNBReleaseConfirm_IEs__value_PR_SgNB_UE_X2AP_ID;
ie->value.choice.SgNB_UE_X2AP_ID = sgnb_ue_x2ap_id;
ASN_SEQUENCE_ADD(&out->protocolIEs.list, ie);
if (x2ap_eNB_encode_pdu(&pdu, &buffer, &len) < 0) {
X2AP_ERROR("Failed to encode ENDC X2 SgNB Release Request Acknowledge\n");
return -1;
}
x2ap_eNB_itti_send_sctp_data_req(instance_p->instance, x2ap_eNB_data_p->assoc_id, buffer, len, 0);
return ret;
}
......@@ -77,4 +77,16 @@ int x2ap_gNB_generate_ENDC_x2_SgNB_addition_request_ACK( x2ap_eNB_instance_t *in
int x2ap_eNB_generate_ENDC_x2_SgNB_reconfiguration_complete(
x2ap_eNB_instance_t *instance_p, x2ap_eNB_data_t *x2ap_eNB_data_p, int ue_id, int SgNB_ue_id);
int x2ap_eNB_generate_ENDC_x2_SgNB_release_request(x2ap_eNB_instance_t *instance_p, x2ap_eNB_data_t *x2ap_eNB_data_p,
int x2_id_source, int x2_id_target, x2ap_cause_t cause);
int x2ap_gNB_generate_ENDC_x2_SgNB_release_request_acknowledge(x2ap_eNB_instance_t *instance_p, x2ap_eNB_data_t *x2ap_eNB_data_p,
int menb_ue_x2ap_id, int sgnb_ue_x2ap_id);
int x2ap_eNB_generate_ENDC_x2_SgNB_release_required(x2ap_eNB_instance_t *instance_p, x2ap_eNB_data_t *x2ap_eNB_data_p,
int x2_id_source, int x2_id_target, x2ap_cause_t cause);
int x2ap_gNB_generate_ENDC_x2_SgNB_release_confirm(x2ap_eNB_instance_t *instance_p, x2ap_eNB_data_t *x2ap_eNB_data_p,
int menb_ue_x2ap_id, int sgnb_ue_x2ap_id);
#endif /* X2AP_ENB_GENERATE_MESSAGES_H_ */
This diff is collapsed.
......@@ -70,6 +70,16 @@ int x2ap_find_id_from_id_source(x2ap_id_manager *m, int id_source)
return -1;
}
int x2ap_find_id_from_id_target(x2ap_id_manager *m, int id_target)
{
int i;
for (i = 0; i < X2AP_MAX_IDS; i++)
if (m->ids[i].rnti != -1 &&
m->ids[i].id_target == id_target)
return i;
return -1;
}
int x2ap_find_id_from_rnti(x2ap_id_manager *m, int rnti)
{
int i;
......@@ -107,6 +117,16 @@ void x2ap_set_reloc_overall_timer(x2ap_id_manager *m, int ue_id, uint64_t time)
m->ids[ue_id].tx2_reloc_overall_start = time;
}
void x2ap_set_dc_prep_timer(x2ap_id_manager *m, int ue_id, uint64_t time)
{
m->ids[ue_id].t_dc_prep_start = time;
}
void x2ap_set_dc_overall_timer(x2ap_id_manager *m, int ue_id, uint64_t time)
{
m->ids[ue_id].t_dc_overall_start = time;
}
int x2ap_id_get_id_source(x2ap_id_manager *m, int ue_id)
{
return m->ids[ue_id].id_source;
......
......@@ -38,7 +38,8 @@ typedef enum {
X2ID_STATE_SOURCE_PREPARE,
X2ID_STATE_SOURCE_OVERALL,
X2ID_STATE_TARGET,
X2ID_STATE_NSA_PREPARE,
X2ID_STATE_NSA_ENB_PREPARE,
X2ID_STATE_NSA_GNB_OVERALL,
} x2id_state_t;
typedef struct {
......@@ -55,6 +56,8 @@ typedef struct {
/* timers */
uint64_t t_reloc_prep_start;
uint64_t tx2_reloc_overall_start;
uint64_t t_dc_prep_start;
uint64_t t_dc_overall_start;
} x2ap_id;
typedef struct {
......@@ -66,6 +69,7 @@ int x2ap_allocate_new_id(x2ap_id_manager *m);
void x2ap_release_id(x2ap_id_manager *m, int id);
int x2ap_find_id(x2ap_id_manager *, int id_source, int id_target);
int x2ap_find_id_from_id_source(x2ap_id_manager *, int id_source);
int x2ap_find_id_from_id_target(x2ap_id_manager *, int id_source);
int x2ap_find_id_from_rnti(x2ap_id_manager *, int rnti);
void x2ap_set_ids(x2ap_id_manager *m, int ue_id, int rnti, int id_source, int id_target);
void x2ap_id_set_state(x2ap_id_manager *m, int ue_id, x2id_state_t state);
......@@ -73,6 +77,8 @@ void x2ap_id_set_state(x2ap_id_manager *m, int ue_id, x2id_state_t state);
void x2ap_id_set_target(x2ap_id_manager *m, int ue_id, void *target);
void x2ap_set_reloc_prep_timer(x2ap_id_manager *m, int ue_id, uint64_t time);
void x2ap_set_reloc_overall_timer(x2ap_id_manager *m, int ue_id, uint64_t time);
void x2ap_set_dc_prep_timer(x2ap_id_manager *m, int ue_id, uint64_t time);
void x2ap_set_dc_overall_timer(x2ap_id_manager *m, int ue_id, uint64_t time);
int x2ap_id_get_id_source(x2ap_id_manager *m, int ue_id);
int x2ap_id_get_id_target(x2ap_id_manager *m, int ue_id);
int x2ap_id_get_rnti(x2ap_id_manager *m, int ue_id);
......
......@@ -28,11 +28,17 @@
#include "x2ap_eNB_management_procedures.h"
#include "x2ap_eNB_generate_messages.h"
void x2ap_timers_init(x2ap_timers_t *t, int t_reloc_prep, int tx2_reloc_overall)
void x2ap_timers_init(x2ap_timers_t *t,
int t_reloc_prep,
int tx2_reloc_overall,
int t_dc_prep,
int t_dc_overall)
{
t->tti = 0;
t->t_reloc_prep = t_reloc_prep;
t->tx2_reloc_overall = tx2_reloc_overall;
t->t_dc_prep = t_dc_prep;
t->t_dc_overall = t_dc_overall;
}
void x2ap_check_timers(instance_t instance)
......@@ -59,14 +65,17 @@ void x2ap_check_timers(instance_t instance)
for (i = 0; i < X2AP_MAX_IDS; i++) {
if (m->ids[i].rnti == -1) continue;
x2_ongoing++;
if (m->ids[i].state == X2ID_STATE_SOURCE_PREPARE ||
m->ids[i].state == X2ID_STATE_SOURCE_OVERALL)
x2_ongoing++;
if (m->ids[i].state == X2ID_STATE_SOURCE_PREPARE &&
t->tti > m->ids[i].t_reloc_prep_start + t->t_reloc_prep) {
LOG_I(X2AP, "X2 timeout reloc prep\n");
/* t_reloc_prep timed out */
cause = X2AP_T_RELOC_PREP_TIMEOUT;
goto timeout;
goto lte_handover_timeout;
}
if (m->ids[i].state == X2ID_STATE_SOURCE_OVERALL &&
......@@ -74,13 +83,62 @@ void x2ap_check_timers(instance_t instance)
LOG_I(X2AP, "X2 timeout reloc overall\n");
/* tx2_reloc_overall timed out */
cause = X2AP_TX2_RELOC_OVERALL_TIMEOUT;
goto timeout;