handover test

This commit is contained in:
Sukchan Lee 2018-03-13 23:16:01 +09:00
parent 99a8e06ccf
commit dbdd6bfdcf
7 changed files with 357 additions and 160 deletions

View File

@ -1451,27 +1451,20 @@ status_t s1ap_build_handover_command(pkbuf_t **s1apbuf, enb_ue_t *source_ue)
S1AP_E_RABDataForwardingItemIEs_t *item = NULL;
S1AP_E_RABDataForwardingItem_t *e_rab = NULL;
if (MME_HAVE_SGW_DL_INDIRECT_TUNNEL(bearer) ||
MME_HAVE_SGW_UL_INDIRECT_TUNNEL(bearer))
{
item = core_calloc(
1, sizeof(S1AP_E_RABDataForwardingItemIEs_t));
ASN_SEQUENCE_ADD(&E_RABSubjecttoDataForwardingList->list, item);
item = core_calloc(
1, sizeof(S1AP_E_RABDataForwardingItemIEs_t));
ASN_SEQUENCE_ADD(&E_RABSubjecttoDataForwardingList->list, item);
item->id = S1AP_ProtocolIE_ID_id_E_RABDataForwardingItem;
item->criticality = S1AP_Criticality_ignore;
item->value.present = S1AP_E_RABDataForwardingItemIEs__value_PR_E_RABDataForwardingItem;
item->id = S1AP_ProtocolIE_ID_id_E_RABDataForwardingItem;
item->criticality = S1AP_Criticality_ignore;
item->value.present = S1AP_E_RABDataForwardingItemIEs__value_PR_E_RABDataForwardingItem;
e_rab = &item->value.choice.E_RABDataForwardingItem;
e_rab = &item->value.choice.E_RABDataForwardingItem;
e_rab = (S1AP_E_RABDataForwardingItem_t *)
core_calloc(1, sizeof(S1AP_E_RABDataForwardingItem_t));
e_rab->e_RAB_ID = bearer->ebi;
}
e_rab->e_RAB_ID = bearer->ebi;
if (MME_HAVE_SGW_DL_INDIRECT_TUNNEL(bearer))
{
d_assert(e_rab, return CORE_ERROR,);
e_rab->dL_transportLayerAddress =
(S1AP_TransportLayerAddress_t *)
core_calloc(1, sizeof(S1AP_TransportLayerAddress_t));
@ -1486,9 +1479,8 @@ status_t s1ap_build_handover_command(pkbuf_t **s1apbuf, enb_ue_t *source_ue)
d_trace(5, " SGW-DL-TEID[%d]\n", bearer->sgw_dl_teid);
}
if (e_rab && MME_HAVE_SGW_UL_INDIRECT_TUNNEL(bearer))
if (MME_HAVE_SGW_UL_INDIRECT_TUNNEL(bearer))
{
d_assert(e_rab, return CORE_ERROR,);
e_rab->uL_TransportLayerAddress =
(S1AP_TransportLayerAddress_t *)
core_calloc(1, sizeof(S1AP_TransportLayerAddress_t));
@ -1611,7 +1603,13 @@ status_t s1ap_build_handover_preparation_failure(
status_t s1ap_build_handover_request(
pkbuf_t **s1apbuf, mme_ue_t *mme_ue, enb_ue_t *target_ue,
S1AP_HandoverRequiredIEs_t *required)
S1AP_ENB_UE_S1AP_ID_t *enb_ue_s1ap_id,
S1AP_MME_UE_S1AP_ID_t *mme_ue_s1ap_id,
S1AP_HandoverType_t *handovertype,
S1AP_Cause_t *cause,
S1AP_TargetID_t *targetid,
S1AP_Source_ToTarget_TransparentContainer_t
*source_totarget_transparentContainer)
{
status_t rv;
@ -1634,9 +1632,12 @@ status_t s1ap_build_handover_request(
mme_bearer_t *bearer = NULL;
s6a_subscription_data_t *subscription_data = NULL;
d_assert(handovertype, return CORE_ERROR,);
d_assert(cause, return CORE_ERROR,);
d_assert(source_totarget_transparentContainer, return CORE_ERROR,);
d_assert(target_ue, return CORE_ERROR, "Null param");
d_assert(mme_ue, return CORE_ERROR, "Null param");
d_assert(required, return CORE_ERROR, "Null param");
subscription_data = &mme_ue->subscription_data;
d_assert(subscription_data, return CORE_ERROR, "Null param");
@ -1733,10 +1734,9 @@ status_t s1ap_build_handover_request(
SecurityContext = &ie->value.choice.SecurityContext;
*MME_UE_S1AP_ID = target_ue->mme_ue_s1ap_id;
*HandoverType = required->value.choice.HandoverType;
Cause->present = required->value.choice.Cause.present;
Cause->choice.radioNetwork =
required->value.choice.Cause.choice.radioNetwork;
*HandoverType = *handovertype;
Cause->present = cause->present;
Cause->choice.radioNetwork = cause->choice.radioNetwork;
asn_uint642INTEGER(
&UEAggregateMaximumBitrate->uEaggregateMaximumBitRateUL,
@ -1815,8 +1815,8 @@ status_t s1ap_build_handover_request(
}
s1ap_buffer_to_OCTET_STRING(
required->value.choice.Source_ToTarget_TransparentContainer.buf,
required->value.choice.Source_ToTarget_TransparentContainer.size,
source_totarget_transparentContainer->buf,
source_totarget_transparentContainer->size,
Source_ToTarget_TransparentContainer);
UESecurityCapabilities->encryptionAlgorithms.size = 2;
@ -1925,10 +1925,12 @@ status_t s1ap_build_handover_cancel_ack(pkbuf_t **s1apbuf, enb_ue_t *source_ue)
}
status_t s1ap_build_mme_status_transfer(pkbuf_t **s1apbuf,
enb_ue_t *target_ue, S1AP_ENBStatusTransferIEs_t *enb_ies)
enb_ue_t *target_ue,
S1AP_ENB_StatusTransfer_TransparentContainer_t
*enb_statustransfer_transparentContainer)
{
status_t rv;
int i;
// int i;
S1AP_S1AP_PDU_t pdu;
S1AP_InitiatingMessage_t *initiatingMessage = NULL;
@ -1943,7 +1945,7 @@ status_t s1ap_build_mme_status_transfer(pkbuf_t **s1apbuf,
#endif
d_assert(target_ue, return CORE_ERROR,);
d_assert(enb_ies, return CORE_ERROR,);
d_assert(enb_statustransfer_transparentContainer, return CORE_ERROR,);
d_trace(3, "[MME] MME status transfer\n");
@ -1978,6 +1980,7 @@ status_t s1ap_build_mme_status_transfer(pkbuf_t **s1apbuf,
ENB_UE_S1AP_ID = &ie->value.choice.ENB_UE_S1AP_ID;
#if 0
ie = core_calloc(1, sizeof(S1AP_MMEStatusTransferIEs_t));
ASN_SEQUENCE_ADD(&MMEStatusTransfer->protocolIEs, ie);
@ -1986,7 +1989,6 @@ status_t s1ap_build_mme_status_transfer(pkbuf_t **s1apbuf,
ie->value.present =
S1AP_MMEStatusTransferIEs__value_PR_ENB_StatusTransfer_TransparentContainer;
#if 0
ENB_StatusTransfer_TransparentContainer =
&ie->value.choice.ENB_StatusTransfer_TransparentContainer;
#endif
@ -1997,11 +1999,11 @@ status_t s1ap_build_mme_status_transfer(pkbuf_t **s1apbuf,
d_trace(5, " Target : ENB_UE_S1AP_ID[%d] MME_UE_S1AP_ID[%d]\n",
target_ue->enb_ue_s1ap_id, target_ue->mme_ue_s1ap_id);
#if 0
for (i = 0; i < enb_ies->value.choice.
ENB_StatusTransfer_TransparentContainer.
bearers_SubjectToStatusTransferList.list.count; i++)
{
#if 0
S1AP_Bearers_SubjectToStatusTransferList_IEs_t *mme_ie = NULL;
S1AP_Bearers_SubjectToStatusTransferList_t *mme_list = NULL;
S1AP_IE_t *enb_ie = NULL, *mme_ie = NULL;
@ -2017,8 +2019,8 @@ status_t s1ap_build_mme_status_transfer(pkbuf_t **s1apbuf,
ASN_SEQUENCE_ADD(&mme_ies->
eNB_StatusTransfer_TransparentContainer.
bearers_SubjectToStatusTransferList, mme_ie);
#endif
}
#endif
rv = s1ap_encode_pdu(s1apbuf, &pdu);
s1ap_free_pdu(&pdu);

View File

@ -38,13 +38,21 @@ CORE_DECLARE(status_t) s1ap_build_handover_preparation_failure(
CORE_DECLARE(status_t) s1ap_build_handover_request(
pkbuf_t **s1apbuf, mme_ue_t *mme_ue, enb_ue_t *target_ue,
S1AP_HandoverRequiredIEs_t *required);
S1AP_ENB_UE_S1AP_ID_t *enb_ue_s1ap_id,
S1AP_MME_UE_S1AP_ID_t *mme_ue_s1ap_id,
S1AP_HandoverType_t *handovertype,
S1AP_Cause_t *cause,
S1AP_TargetID_t *targetid,
S1AP_Source_ToTarget_TransparentContainer_t
*source_totarget_transparentContainer);
CORE_DECLARE(status_t) s1ap_build_handover_cancel_ack(
pkbuf_t **s1apbuf, enb_ue_t *source_ue);
CORE_DECLARE(status_t) s1ap_build_mme_status_transfer(pkbuf_t **s1apbuf,
enb_ue_t *target_ue, S1AP_ENBStatusTransferIEs_t *enb_ies);
enb_ue_t *target_ue,
S1AP_ENB_StatusTransfer_TransparentContainer_t
*enb_statustransfer_transparentContainer);
CORE_DECLARE(status_t) s1ap_build_error_indication(
pkbuf_t **s1apbuf,

View File

@ -1267,34 +1267,165 @@ void s1ap_handle_path_switch_request(
enb_ue_switch_to_enb(enb_ue, enb);
}
#if 0
void s1ap_handle_enb_configuration_transfer(
mme_enb_t *enb, s1ap_message_t *message, pkbuf_t *pkbuf)
{
status_t rv;
char buf[CORE_ADDRSTRLEN];
int i;
S1AP_InitiatingMessage_t *initiatingMessage = NULL;
S1AP_ENBConfigurationTransfer_t *ENBConfigurationTransfer = NULL;
S1AP_ENBConfigurationTransferIEs_t *ie = NULL;
S1AP_SONConfigurationTransfer_t *SONConfigurationTransfer = NULL;
d_assert(enb, return,);
d_assert(enb->sock, return,);
d_assert(message, return,);
initiatingMessage = message->choice.initiatingMessage;
d_assert(initiatingMessage, return,);
ENBConfigurationTransfer =
&initiatingMessage->value.choice.ENBConfigurationTransfer;
d_assert(ENBConfigurationTransfer, return,);
d_trace(3, "[MME] ENB configuration transfer\n");
for (i = 0; i < ENBConfigurationTransfer->protocolIEs.list.count; i++)
{
ie = ENBConfigurationTransfer->protocolIEs.list.array[i];
switch(ie->id)
{
case S1AP_ProtocolIE_ID_id_SONConfigurationTransferECT:
SONConfigurationTransfer =
&ie->value.choice.SONConfigurationTransfer;
break;
default:
break;
}
}
d_trace(5, " IP[%s] ENB_ID[%d]\n",
CORE_ADDR(enb->addr, buf), enb->enb_id);
if (SONConfigurationTransfer)
{
S1AP_SONConfigurationTransfer_t *transfer = SONConfigurationTransfer;
mme_enb_t *target_enb = NULL;
c_uint32_t source_enb_id, target_enb_id;
c_uint16_t source_tac, target_tac;
d_assert(transfer, return,);
s1ap_ENB_ID_to_uint32(
&transfer->sourceeNB_ID.global_ENB_ID.eNB_ID,
&source_enb_id);
s1ap_ENB_ID_to_uint32(
&transfer->targeteNB_ID.global_ENB_ID.eNB_ID,
&target_enb_id);
memcpy(&source_tac, transfer->sourceeNB_ID.selected_TAI.tAC.buf,
sizeof(source_tac));
source_tac = ntohs(source_tac);
memcpy(&target_tac, transfer->targeteNB_ID.selected_TAI.tAC.buf,
sizeof(target_tac));
target_tac = ntohs(target_tac);
d_trace(5, " Source : ENB_ID[%s:%d], TAC[%d]\n",
transfer->sourceeNB_ID.global_ENB_ID.eNB_ID.present ==
S1AP_ENB_ID_PR_homeENB_ID ? "Home" :
transfer->sourceeNB_ID.global_ENB_ID.eNB_ID.present ==
S1AP_ENB_ID_PR_macroENB_ID ? "Macro" : "Others",
source_enb_id, source_tac);
d_trace(5, " Target : ENB_ID[%s:%d], TAC[%d]\n",
transfer->targeteNB_ID.global_ENB_ID.eNB_ID.present ==
S1AP_ENB_ID_PR_homeENB_ID ? "Home" :
transfer->targeteNB_ID.global_ENB_ID.eNB_ID.present ==
S1AP_ENB_ID_PR_macroENB_ID ? "Macro" : "Others",
target_enb_id, target_tac);
target_enb = mme_enb_find_by_enb_id(target_enb_id);
d_assert(target_enb, return,
"Cannot find target eNB = %d", target_enb_id);
rv = s1ap_send_mme_configuration_transfer(target_enb, pkbuf);
d_assert(rv == CORE_OK,,);
}
}
void s1ap_handle_handover_required(mme_enb_t *enb, s1ap_message_t *message)
{
status_t rv;
char buf[CORE_ADDRSTRLEN];
int i;
S1AP_InitiatingMessage_t *initiatingMessage = NULL;
S1AP_HandoverRequired_t *HandoverRequired = NULL;
S1AP_HandoverRequiredIEs_t *ie = NULL;
S1AP_ENB_UE_S1AP_ID_t *ENB_UE_S1AP_ID = NULL;
S1AP_MME_UE_S1AP_ID_t *MME_UE_S1AP_ID = NULL;
S1AP_HandoverType_t *HandoverType = NULL;
S1AP_Cause_t *Cause = NULL;
S1AP_TargetID_t *TargetID = NULL;
S1AP_Source_ToTarget_TransparentContainer_t
*Source_ToTarget_TransparentContainer = NULL;
d_assert(enb, return,);
d_assert(enb->sock, return,);
d_assert(message, return,);
initiatingMessage = message->choice.initiatingMessage;
d_assert(initiatingMessage, return,);
HandoverRequired = &initiatingMessage->value.choice.HandoverRequired;
d_assert(HandoverRequired, return,);
enb_ue_t *source_ue = NULL;
mme_ue_t *mme_ue = NULL;
S1AP_HandoverRequiredIEs_t *ies = NULL;
d_assert(enb, return,);
ies = &message->s1ap_HandoverRequiredIEs;
d_assert(ies, return,);
d_trace(3, "[MME] Handover required\n");
for (i = 0; i < HandoverRequired->protocolIEs.list.count; i++)
{
ie = HandoverRequired->protocolIEs.list.array[i];
switch(ie->id)
{
case S1AP_ProtocolIE_ID_id_eNB_UE_S1AP_ID:
ENB_UE_S1AP_ID = &ie->value.choice.ENB_UE_S1AP_ID;
break;
case S1AP_ProtocolIE_ID_id_MME_UE_S1AP_ID:
MME_UE_S1AP_ID = &ie->value.choice.MME_UE_S1AP_ID;
break;
case S1AP_ProtocolIE_ID_id_HandoverType:
HandoverType = &ie->value.choice.HandoverType;
break;
case S1AP_ProtocolIE_ID_id_Cause:
Cause = &ie->value.choice.Cause;
break;
case S1AP_ProtocolIE_ID_id_TargetID:
TargetID = &ie->value.choice.TargetID;
break;
case S1AP_ProtocolIE_ID_id_Source_ToTarget_TransparentContainer:
Source_ToTarget_TransparentContainer =
&ie->value.choice.Source_ToTarget_TransparentContainer;
break;
default:
break;
}
}
d_trace(5, " IP[%s] ENB_ID[%d]\n",
CORE_ADDR(enb->addr, buf), enb->enb_id);
source_ue = enb_ue_find_by_enb_ue_s1ap_id(enb, ies->eNB_UE_S1AP_ID);
d_assert(ENB_UE_S1AP_ID, return,);
d_assert(MME_UE_S1AP_ID, return,);
source_ue = enb_ue_find_by_enb_ue_s1ap_id(enb, *ENB_UE_S1AP_ID);
d_assert(source_ue, return,
"Cannot find UE for eNB-UE-S1AP-ID[%d] and eNB[%s:%d]",
ies->eNB_UE_S1AP_ID,
*ENB_UE_S1AP_ID,
CORE_ADDR(enb->addr, buf), enb->enb_id);
d_assert(source_ue->mme_ue_s1ap_id == ies->mme_ue_s1ap_id, return,
d_assert(source_ue->mme_ue_s1ap_id == *MME_UE_S1AP_ID, return,
"Conflict MME-UE-S1AP-ID : %d != %d\n",
source_ue->mme_ue_s1ap_id, ies->mme_ue_s1ap_id);
source_ue->mme_ue_s1ap_id, *MME_UE_S1AP_ID);
d_trace(5, " Source : ENB_UE_S1AP_ID[%d] MME_UE_S1AP_ID[%d]\n",
source_ue->enb_ue_s1ap_id, source_ue->mme_ue_s1ap_id);
@ -1309,15 +1440,21 @@ void s1ap_handle_handover_required(mme_enb_t *enb, s1ap_message_t *message)
}
else
{
rv = s1ap_send_handover_preparation_failure(source_ue, &ies->cause);
d_assert(Cause, return,);
rv = s1ap_send_handover_preparation_failure(source_ue, Cause);
d_assert(rv == CORE_OK, return, "s1ap send error");
return;
}
source_ue->handover_type = ies->handoverType;
d_assert(HandoverType, return,);
source_ue->handover_type = *HandoverType;
rv = s1ap_send_handover_request(mme_ue, ies);
rv = s1ap_send_handover_request(mme_ue,
ENB_UE_S1AP_ID, MME_UE_S1AP_ID,
HandoverType, Cause, TargetID,
Source_ToTarget_TransparentContainer);
d_assert(rv == CORE_OK,, "s1ap send error");
}
@ -1327,28 +1464,68 @@ void s1ap_handle_handover_request_ack(mme_enb_t *enb, s1ap_message_t *message)
char buf[CORE_ADDRSTRLEN];
int i;
S1AP_SuccessfulOutcome_t *successfulOutcome = NULL;
S1AP_HandoverRequestAcknowledge_t *HandoverRequestAcknowledge = NULL;
S1AP_HandoverRequestAcknowledgeIEs_t *ie = NULL;
S1AP_MME_UE_S1AP_ID_t *MME_UE_S1AP_ID = NULL;
S1AP_ENB_UE_S1AP_ID_t *ENB_UE_S1AP_ID = NULL;
S1AP_E_RABAdmittedList_t *E_RABAdmittedList = NULL;
S1AP_Target_ToSource_TransparentContainer_t
*Target_ToSource_TransparentContainer = NULL;
enb_ue_t *source_ue = NULL;
enb_ue_t *target_ue = NULL;
mme_ue_t *mme_ue = NULL;
S1AP_HandoverRequestAcknowledgeIEs_t *ies = NULL;
d_assert(enb, return,);
d_assert(enb->sock, return,);
ies = &message->s1ap_HandoverRequestAcknowledgeIEs;
d_assert(ies, return,);
d_assert(message, return,);
successfulOutcome = message->choice.successfulOutcome;
d_assert(successfulOutcome, return,);
HandoverRequestAcknowledge =
&successfulOutcome->value.choice.HandoverRequestAcknowledge;
d_assert(HandoverRequestAcknowledge, return,);
d_trace(3, "[MME] Handover request acknowledge\n");
for (i = 0; i < HandoverRequestAcknowledge->protocolIEs.list.count; i++)
{
ie = HandoverRequestAcknowledge->protocolIEs.list.array[i];
switch(ie->id)
{
case S1AP_ProtocolIE_ID_id_MME_UE_S1AP_ID:
MME_UE_S1AP_ID = &ie->value.choice.MME_UE_S1AP_ID;
break;
case S1AP_ProtocolIE_ID_id_eNB_UE_S1AP_ID:
ENB_UE_S1AP_ID = &ie->value.choice.ENB_UE_S1AP_ID;
break;
case S1AP_ProtocolIE_ID_id_E_RABAdmittedList:
E_RABAdmittedList = &ie->value.choice.E_RABAdmittedList;
break;
case S1AP_ProtocolIE_ID_id_Target_ToSource_TransparentContainer:
Target_ToSource_TransparentContainer =
&ie->value.choice.Target_ToSource_TransparentContainer;
break;
default:
break;
}
}
d_trace(5, " IP[%s] ENB_ID[%d]\n",
CORE_ADDR(enb->addr, buf), enb->enb_id);
target_ue = enb_ue_find_by_mme_ue_s1ap_id(ies->mme_ue_s1ap_id);
d_assert(MME_UE_S1AP_ID, return,);
d_assert(ENB_UE_S1AP_ID, return,);
d_assert(E_RABAdmittedList, return,);
d_assert(Target_ToSource_TransparentContainer, return,);
target_ue = enb_ue_find_by_mme_ue_s1ap_id(*MME_UE_S1AP_ID);
d_assert(target_ue, return,
"Cannot find UE for MME-UE-S1AP-ID[%d] and eNB[%s:%d]",
ies->mme_ue_s1ap_id,
*MME_UE_S1AP_ID,
CORE_ADDR(enb->addr, buf), enb->enb_id);
target_ue->enb_ue_s1ap_id = ies->eNB_UE_S1AP_ID;
target_ue->enb_ue_s1ap_id = *ENB_UE_S1AP_ID;
source_ue = target_ue->source_ue;
d_assert(source_ue, return,);
@ -1360,17 +1537,21 @@ void s1ap_handle_handover_request_ack(mme_enb_t *enb, s1ap_message_t *message)
d_trace(5, " Target : ENB_UE_S1AP_ID[%d] MME_UE_S1AP_ID[%d]\n",
target_ue->enb_ue_s1ap_id, target_ue->mme_ue_s1ap_id);
for (i = 0; i < ies->e_RABAdmittedList.s1ap_E_RABAdmittedItem.count; i++)
for (i = 0; i < E_RABAdmittedList->list.count; i++)
{
mme_bearer_t *bearer = NULL;
S1AP_E_RABAdmittedItemIEs_t *item = NULL;
S1AP_E_RABAdmittedItem_t *e_rab = NULL;
e_rab = (S1AP_E_RABAdmittedItem_t *)ies->e_RABAdmittedList.
s1ap_E_RABAdmittedItem.array[i];
d_assert(e_rab, return, "Null param");
mme_bearer_t *bearer = NULL;
item = (S1AP_E_RABAdmittedItemIEs_t *)E_RABAdmittedList->list.array[i];
d_assert(item, return,);
e_rab = &item->value.choice.E_RABAdmittedItem;
d_assert(e_rab, return,);
bearer = mme_bearer_find_by_ue_ebi(mme_ue, e_rab->e_RAB_ID);
d_assert(bearer, return, "Null param");
d_assert(bearer, return,);
memcpy(&bearer->target_s1u_teid, e_rab->gTP_TEID.buf,
sizeof(bearer->target_s1u_teid));
@ -1391,21 +1572,21 @@ void s1ap_handle_handover_request_ack(mme_enb_t *enb, s1ap_message_t *message)
d_assert(rv == CORE_OK, return,);
}
if (e_rab->uL_S1AP_TransportLayerAddress && e_rab->uL_S1AP_GTP_TEID)
if (e_rab->uL_TransportLayerAddress && e_rab->uL_GTP_TEID)
{
d_assert(e_rab->uL_S1AP_GTP_TEID->buf, return,);
d_assert(e_rab->uL_S1AP_TransportLayerAddress->buf, return,);
memcpy(&bearer->enb_ul_teid, e_rab->uL_S1AP_GTP_TEID->buf,
d_assert(e_rab->uL_GTP_TEID->buf, return,);
d_assert(e_rab->uL_TransportLayerAddress->buf, return,);
memcpy(&bearer->enb_ul_teid, e_rab->uL_GTP_TEID->buf,
sizeof(bearer->enb_ul_teid));
bearer->enb_ul_teid = ntohl(bearer->enb_ul_teid);
rv = s1ap_BIT_STRING_to_ip(
e_rab->uL_S1AP_TransportLayerAddress, &bearer->enb_ul_ip);
e_rab->uL_TransportLayerAddress, &bearer->enb_ul_ip);
d_assert(rv == CORE_OK, return,);
}
}
S1AP_STORE_DATA(
&mme_ue->container, &ies->target_ToSource_TransparentContainer);
&mme_ue->container, Target_ToSource_TransparentContainer);
if (mme_ue_have_indirect_tunnel(mme_ue) == 1)
{
@ -1420,6 +1601,7 @@ void s1ap_handle_handover_request_ack(mme_enb_t *enb, s1ap_message_t *message)
}
}
#if 0
void s1ap_handle_handover_failure(mme_enb_t *enb, s1ap_message_t *message)
{
status_t rv;
@ -1512,33 +1694,69 @@ void s1ap_handle_handover_cancel(mme_enb_t *enb, s1ap_message_t *message)
source_ue->enb_ue_s1ap_id,
CORE_ADDR(enb->addr, buf), enb->enb_id);
}
#endif
void s1ap_handle_enb_status_transfer(mme_enb_t *enb, s1ap_message_t *message)
{
status_t rv;
char buf[CORE_ADDRSTRLEN];
int i;
S1AP_InitiatingMessage_t *initiatingMessage = NULL;
S1AP_ENBStatusTransfer_t *ENBStatusTransfer = NULL;
S1AP_ENBStatusTransferIEs_t *ie = NULL;
S1AP_MME_UE_S1AP_ID_t *MME_UE_S1AP_ID = NULL;
S1AP_ENB_UE_S1AP_ID_t *ENB_UE_S1AP_ID = NULL;
S1AP_ENB_StatusTransfer_TransparentContainer_t
*ENB_StatusTransfer_TransparentContainer = NULL;
enb_ue_t *source_ue = NULL, *target_ue = NULL;
S1AP_ENBStatusTransferIEs_t *ies = NULL;
d_assert(enb, return,);
d_assert(enb->sock, return,);
ies = &message->s1ap_ENBStatusTransferIEs;
d_assert(ies, return,);
d_assert(message, return,);
initiatingMessage = message->choice.initiatingMessage;
d_assert(initiatingMessage, return,);
ENBStatusTransfer = &initiatingMessage->value.choice.ENBStatusTransfer;
d_assert(ENBStatusTransfer, return,);
d_trace(3, "[MME] ENB status transfer\n");
for (i = 0; i < ENBStatusTransfer->protocolIEs.list.count; i++)
{
ie = ENBStatusTransfer->protocolIEs.list.array[i];
switch(ie->id)
{
case S1AP_ProtocolIE_ID_id_MME_UE_S1AP_ID:
MME_UE_S1AP_ID = &ie->value.choice.MME_UE_S1AP_ID;
break;
case S1AP_ProtocolIE_ID_id_eNB_UE_S1AP_ID:
ENB_UE_S1AP_ID = &ie->value.choice.ENB_UE_S1AP_ID;
break;
case S1AP_ProtocolIE_ID_id_eNB_StatusTransfer_TransparentContainer:
ENB_StatusTransfer_TransparentContainer =
&ie->value.choice.ENB_StatusTransfer_TransparentContainer;
break;
default:
break;
}
}
d_trace(5, " IP[%s] ENB_ID[%d]\n",
CORE_ADDR(enb->addr, buf), enb->enb_id);
source_ue = enb_ue_find_by_enb_ue_s1ap_id(enb, ies->eNB_UE_S1AP_ID);
d_assert(MME_UE_S1AP_ID, return,);
d_assert(ENB_UE_S1AP_ID, return,);
d_assert(ENB_StatusTransfer_TransparentContainer, return,);
source_ue = enb_ue_find_by_enb_ue_s1ap_id(enb, *ENB_UE_S1AP_ID);
d_assert(source_ue, return,
"Cannot find UE for eNB-UE-S1AP-ID[%d] and eNB[%s:%d]",
ies->eNB_UE_S1AP_ID,
*ENB_UE_S1AP_ID,
CORE_ADDR(enb->addr, buf), enb->enb_id);
d_assert(source_ue->mme_ue_s1ap_id == ies->mme_ue_s1ap_id, return,
d_assert(source_ue->mme_ue_s1ap_id == *MME_UE_S1AP_ID, return,
"Conflict MME-UE-S1AP-ID : %d != %d\n",
source_ue->mme_ue_s1ap_id, ies->mme_ue_s1ap_id);
source_ue->mme_ue_s1ap_id, *MME_UE_S1AP_ID);
target_ue = source_ue->target_ue;
d_assert(target_ue, return,);
@ -1548,72 +1766,12 @@ void s1ap_handle_enb_status_transfer(mme_enb_t *enb, s1ap_message_t *message)
d_trace(5, " Target : ENB_UE_S1AP_ID[%d] MME_UE_S1AP_ID[%d]\n",
target_ue->enb_ue_s1ap_id, target_ue->mme_ue_s1ap_id);
rv = s1ap_send_mme_status_transfer(target_ue, ies);
rv = s1ap_send_mme_status_transfer(target_ue,
ENB_StatusTransfer_TransparentContainer);
d_assert(rv == CORE_OK,,);
}
void s1ap_handle_enb_configuration_transfer(
mme_enb_t *enb, s1ap_message_t *message, pkbuf_t *pkbuf)
{
status_t rv;
char buf[CORE_ADDRSTRLEN];
S1AP_ENBConfigurationTransferIEs_t *ies = NULL;
d_assert(enb, return,);
ies = &message->s1ap_ENBConfigurationTransferIEs;
d_assert(ies, return,);
d_trace(3, "[MME] ENB configuration transfer\n");
d_trace(5, " IP[%s] ENB_ID[%d]\n",
CORE_ADDR(enb->addr, buf), enb->enb_id);
if (ies->presenceMask &
S1AP_ENBCONFIGURATIONTRANSFERIES_SONCONFIGURATIONTRANSFERECT_PRESENT)
{
S1AP_SONConfigurationTransfer_t *transfer =
&ies->sonConfigurationTransferECT;
mme_enb_t *target_enb = NULL;
c_uint32_t source_enb_id, target_enb_id;
c_uint16_t source_tac, target_tac;
s1ap_ENB_ID_to_uint32(
&transfer->sourceeNB_ID.global_S1AP_ENB_ID.eNB_ID,
&source_enb_id);
s1ap_ENB_ID_to_uint32(
&transfer->targeteNB_ID.global_S1AP_ENB_ID.eNB_ID,
&target_enb_id);
memcpy(&source_tac, transfer->sourceeNB_ID.selected_S1AP_TAI.tAC.buf,
sizeof(source_tac));
source_tac = ntohs(source_tac);
memcpy(&target_tac, transfer->targeteNB_ID.selected_S1AP_TAI.tAC.buf,
sizeof(target_tac));
target_tac = ntohs(target_tac);
d_trace(5, " Source : ENB_ID[%s:%d], TAC[%d]\n",
transfer->sourceeNB_ID.global_S1AP_ENB_ID.eNB_ID.present ==
S1AP_ENB_ID_PR_homeENB_ID ? "Home" :
transfer->sourceeNB_ID.global_S1AP_ENB_ID.eNB_ID.present ==
S1AP_ENB_ID_PR_macroENB_ID ? "Macro" : "Others",
source_enb_id, source_tac);
d_trace(5, " Target : ENB_ID[%s:%d], TAC[%d]\n",
transfer->targeteNB_ID.global_S1AP_ENB_ID.eNB_ID.present ==
S1AP_ENB_ID_PR_homeENB_ID ? "Home" :
transfer->targeteNB_ID.global_S1AP_ENB_ID.eNB_ID.present ==
S1AP_ENB_ID_PR_macroENB_ID ? "Macro" : "Others",
target_enb_id, target_tac);
target_enb = mme_enb_find_by_enb_id(target_enb_id);
d_assert(target_enb, return,
"Cannot find target eNB = %d", target_enb_id);
rv = s1ap_send_mme_configuration_transfer(target_enb, pkbuf);
d_assert(rv == CORE_OK,,);
}
}
#if 0
void s1ap_handle_handover_notification(mme_enb_t *enb, s1ap_message_t *message)
{
status_t rv;

View File

@ -371,9 +371,15 @@ status_t s1ap_send_handover_cancel_ack(enb_ue_t *source_ue)
status_t s1ap_send_handover_request(
mme_ue_t *mme_ue, S1AP_HandoverRequiredIEs_t *ies)
mme_ue_t *mme_ue,
S1AP_ENB_UE_S1AP_ID_t *enb_ue_s1ap_id,
S1AP_MME_UE_S1AP_ID_t *mme_ue_s1ap_id,
S1AP_HandoverType_t *handovertype,
S1AP_Cause_t *cause,
S1AP_TargetID_t *targetid,
S1AP_Source_ToTarget_TransparentContainer_t
*source_totarget_transparentContainer)
{
#if 0
status_t rv;
pkbuf_t *s1apbuf = NULL;
S1AP_TargetID_t *targetID = NULL;
@ -387,17 +393,15 @@ status_t s1ap_send_handover_request(
d_assert(mme_ue, return CORE_ERROR,);
source_ue = mme_ue->enb_ue;
d_assert(source_ue, return CORE_ERROR,);
d_assert(ies, return CORE_ERROR,);
targetID = &ies->targetID;
d_assert(targetID, return CORE_ERROR,);
d_assert(targetid, return CORE_ERROR,);
switch(targetID->present)
switch(targetid->present)
{
case S1AP_TargetID_PR_targeteNB_ID:
{
s1ap_ENB_ID_to_uint32(
&targetID->choice.targeteNB_ID.global_S1AP_ENB_ID.eNB_ID,
&targetid->choice.targeteNB_ID->global_ENB_ID.eNB_ID,
&enb_id);
break;
}
@ -426,20 +430,22 @@ status_t s1ap_send_handover_request(
rv = source_ue_associate_target_ue(source_ue, target_ue);
d_assert(rv == CORE_OK, return CORE_ERROR,);
rv = s1ap_build_handover_request(&s1apbuf, mme_ue, target_ue, ies);
rv = s1ap_build_handover_request(&s1apbuf, mme_ue, target_ue,
enb_ue_s1ap_id, mme_ue_s1ap_id,
handovertype, cause, targetid,
source_totarget_transparentContainer);
d_assert(rv == CORE_OK && s1apbuf, return CORE_ERROR, "s1ap build error");
rv = s1ap_send_to_enb(target_enb, s1apbuf);
d_assert(rv == CORE_OK,, "s1ap send error");
return rv;
#else
return CORE_OK;
#endif
}
status_t s1ap_send_mme_status_transfer(
enb_ue_t *target_ue, S1AP_ENBStatusTransferIEs_t *ies)
enb_ue_t *target_ue,
S1AP_ENB_StatusTransfer_TransparentContainer_t
*enb_statustransfer_transparentContainer)
{
status_t rv;
pkbuf_t *s1apbuf = NULL;
@ -450,7 +456,8 @@ status_t s1ap_send_mme_status_transfer(
enb = target_ue->enb;
d_assert(enb, return CORE_ERROR,);
rv = s1ap_build_mme_status_transfer(&s1apbuf, target_ue, ies);
rv = s1ap_build_mme_status_transfer(&s1apbuf, target_ue,
enb_statustransfer_transparentContainer);
d_assert(rv == CORE_OK && s1apbuf, return CORE_ERROR, "s1ap build error");
rv = s1ap_send_to_enb(enb, s1apbuf);

View File

@ -44,17 +44,29 @@ CORE_DECLARE(status_t) s1ap_send_path_switch_failure(mme_enb_t *enb,
c_uint32_t enb_ue_s1ap_id, c_uint32_t mme_ue_s1ap_id,
S1AP_Cause_PR group, long cause);
CORE_DECLARE(status_t) s1ap_send_mme_configuration_transfer(
mme_enb_t *target_enb, pkbuf_t *pkbuf);
CORE_DECLARE(status_t) s1ap_send_handover_command(enb_ue_t *source_ue);
CORE_DECLARE(status_t) s1ap_send_handover_preparation_failure(
enb_ue_t *source_ue, S1AP_Cause_t *cause);
CORE_DECLARE(status_t) s1ap_send_handover_request(
mme_ue_t *mme_ue, S1AP_HandoverRequiredIEs_t *required);
mme_ue_t *mme_ue,
S1AP_ENB_UE_S1AP_ID_t *enb_ue_s1ap_id,
S1AP_MME_UE_S1AP_ID_t *mme_ue_s1ap_id,
S1AP_HandoverType_t *handovertype,
S1AP_Cause_t *cause,
S1AP_TargetID_t *targetid,
S1AP_Source_ToTarget_TransparentContainer_t
*source_totarget_transparentContainer);
CORE_DECLARE(status_t) s1ap_send_handover_cancel_ack(enb_ue_t *source_ue);
CORE_DECLARE(status_t) s1ap_send_mme_status_transfer(
enb_ue_t *target_ue, S1AP_ENBStatusTransferIEs_t *ies);
enb_ue_t *target_ue,
S1AP_ENB_StatusTransfer_TransparentContainer_t
*enb_statustransfer_transparentContainer);
CORE_DECLARE(status_t) s1ap_send_error_indication(
mme_enb_t *enb,
S1AP_MME_UE_S1AP_ID_t *mme_ue_s1ap_id,

View File

@ -96,22 +96,33 @@ void s1ap_state_operational(fsm_t *s, event_t *e)
s1ap_handle_path_switch_request(enb, pdu);
break;
}
#if 0
case S1AP_ProcedureCode_id_eNBConfigurationTransfer:
{
pkbuf_t *pkbuf = (pkbuf_t *)event_get_param3(e);
d_assert(pkbuf, break, "Null param");
s1ap_handle_enb_configuration_transfer(
enb, pdu, pkbuf);
break;
}
case S1AP_ProcedureCode_id_HandoverPreparation:
{
s1ap_handle_handover_required(enb, pdu);
break;
}
#if 0
case S1AP_ProcedureCode_id_HandoverCancel:
{
s1ap_handle_handover_cancel(enb, pdu);
break;
}
#endif
case S1AP_ProcedureCode_id_eNBStatusTransfer:
{
s1ap_handle_enb_status_transfer(enb, pdu);
break;
}
#if 0
case S1AP_ProcedureCode_id_HandoverNotification:
{
s1ap_handle_handover_notification(enb, pdu);
@ -162,13 +173,11 @@ void s1ap_state_operational(fsm_t *s, event_t *e)
enb, pdu);
break;
}
#if 0
case S1AP_ProcedureCode_id_HandoverResourceAllocation:
{
s1ap_handle_handover_request_ack(enb, pdu);
break;
}
#endif
default:
{
d_warn("Not implemented(choice:%d, proc:%d)",

View File

@ -343,7 +343,6 @@ static void handover_test1(abts_case *tc, void *data)
core_sleep(time_from_msec(300));
}
#if 0
static void handover_test2(abts_case *tc, void *data)
{
status_t rv;
@ -656,6 +655,11 @@ static void handover_test2(abts_case *tc, void *data)
rv = tests1ap_enb_send(sock1, sendbuf);
ABTS_INT_EQUAL(tc, CORE_OK, rv);
#if 1
core_sleep(time_from_msec(1000));
goto out;
#endif
/* Receive MME Status Transfer */
recvbuf = pkbuf_alloc(0, MAX_SDU_LEN);
rv = tests1ap_enb_read(sock2, recvbuf);
@ -851,16 +855,13 @@ out:
core_sleep(time_from_msec(300));
}
#endif
abts_suite *test_handover(abts_suite *suite)
{
suite = ADD_SUITE(suite)
abts_run_test(suite, handover_test1, NULL);
#if 0
abts_run_test(suite, handover_test2, NULL);
#endif
return suite;
}