Commit 96e00243 authored by Tien-Thinh Nguyen's avatar Tien-Thinh Nguyen

Add HandoverPreparationFailure

parent 40420fef
......@@ -41,6 +41,7 @@
#include "PduSessionResourceReleaseCommand.hpp"
#include "PduSessionResourceSetupRequest.hpp"
#include "UEContextReleaseCommand.hpp"
#include "HandoverPreparationFailure.hpp"
#include "amf_app.hpp"
#include "amf_config.hpp"
#include "amf_n1.hpp"
......@@ -170,7 +171,9 @@ void amf_n2_task(void* args_p) {
Logger::amf_n2().info("Received HANDOVER_REQUIRED message,handling");
itti_handover_required* m = dynamic_cast<itti_handover_required*>(msg);
if (!amf_n2_inst->handle_itti_message(ref(*m)))
amf_n2_inst->send_handover_preparation_failure(m->assoc_id);
amf_n2_inst->send_handover_preparation_failure(
m->handoverReq->getAmfUeNgapId(),
m->handoverReq->getRanUeNgapId(), m->assoc_id);
} break;
case HANDOVER_REQUEST_ACK: {
Logger::amf_n2().info("Received HANDOVER_REQUEST_ACK message,handling");
......@@ -1517,9 +1520,22 @@ void amf_n2::handle_itti_message(itti_uplinkranstatsutransfer& itti_msg) {
//------------------------------------------------------------------------------
void amf_n2::send_handover_preparation_failure(
const unsigned long amf_ue_ngap_id, const uint32_t ran_ue_ngap_id,
const sctp_assoc_id_t& gnb_assoc_id) {
// TODO:
return;
// Create HandoverPreparationFailure message to be sent to target gNB
std::unique_ptr<HandoverPreparationFailure> hoPreparationFailure =
std::make_unique<HandoverPreparationFailure>();
hoPreparationFailure->setMessageType();
hoPreparationFailure->setAmfUeNgapId(amf_ue_ngap_id);
hoPreparationFailure->setRanUeNgapId(amf_ue_ngap_id);
hoPreparationFailure->setCause(Ngap_Cause_PR_NOTHING);
uint8_t buffer[BUFFER_SIZE_1024];
int encoded_size =
hoPreparationFailure->encode2buffer(buffer, BUFFER_SIZE_1024);
bstring b = blk2bstr(buffer, encoded_size);
sctp_s_38412.sctp_send_msg(gnb_assoc_id, 0, &b);
}
// Context management functions
......
......@@ -62,7 +62,9 @@ class amf_n2 : public ngap::ngap_app {
void handle_itti_message(itti_handover_request_Ack& itti_msg);
void handle_itti_message(itti_handover_notify& itti_msg);
void handle_itti_message(itti_uplinkranstatsutransfer& itti_msg);
void send_handover_preparation_failure(const sctp_assoc_id_t& gnb_assoc_id);
void send_handover_preparation_failure(
const unsigned long amf_ue_ngap_id, const uint32_t ran_ue_ngap_id,
const sctp_assoc_id_t& gnb_assoc_id);
bool verifyPlmn(std::vector<SupportedItem_t> list);
std::vector<SupportedItem_t> get_common_plmn(
......
/*
* Licensed to the OpenAirInterface (OAI) Software Alliance under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The OpenAirInterface Software Alliance licenses this file to You under
* the OAI Public License, Version 1.1 (the "License"); you may not use this
* file except in compliance with the License. You may obtain a copy of the
* License at
*
* http://www.openairinterface.org/?page_id=698
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*-------------------------------------------------------------------------------
* For more information about the OpenAirInterface (OAI) Software Alliance:
* contact@openairinterface.org
*/
#include "HandoverPreparationFailure.hpp"
#include "logger.hpp"
extern "C" {
#include "Ngap_NGAP-PDU.h"
#include "asn_codecs.h"
#include "constr_TYPE.h"
#include "constraints.h"
#include "dynamic_memory_check.h"
#include "per_decoder.h"
#include "per_encoder.h"
}
#include <iostream>
#include <vector>
using namespace std;
namespace ngap {
HandoverPreparationFailure::HandoverPreparationFailure() {
amfUeNgapId = NULL;
ranUeNgapId = NULL;
cause = NULL;
hoPreparationFailureIEs = NULL;
CriticalityDiagnostics = NULL;
}
HandoverPreparationFailure::~HandoverPreparationFailure() {}
unsigned long HandoverPreparationFailure::getAmfUeNgapId() const {
if (amfUeNgapId) return amfUeNgapId->getAMF_UE_NGAP_ID();
}
uint32_t HandoverPreparationFailure::getRanUeNgapId() const {
if (ranUeNgapId) return ranUeNgapId->getRanUeNgapId();
}
bool HandoverPreparationFailure::decodefrompdu(Ngap_NGAP_PDU_t* ngap_msg_pdu) {
if (!ngap_msg_pdu) return false;
hoPreparationFailurePdu = ngap_msg_pdu;
if (hoPreparationFailurePdu->present ==
Ngap_NGAP_PDU_PR_unsuccessfulOutcome) {
if (hoPreparationFailurePdu->choice.unsuccessfulOutcome &&
hoPreparationFailurePdu->choice.unsuccessfulOutcome->procedureCode ==
Ngap_ProcedureCode_id_HandoverPreparation &&
hoPreparationFailurePdu->choice.unsuccessfulOutcome->criticality ==
Ngap_Criticality_reject &&
hoPreparationFailurePdu->choice.unsuccessfulOutcome->value.present ==
Ngap_UnsuccessfulOutcome__value_PR_HandoverPreparationFailure) {
hoPreparationFailureIEs =
&hoPreparationFailurePdu->choice.unsuccessfulOutcome->value.choice
.HandoverPreparationFailure;
} else {
Logger::ngap().error("Check HandoverPreparationFailure message error");
return false;
}
} else {
Logger::ngap().error("HandoverPreparationFailure MessageType error");
return false;
}
for (int i = 0; i < hoPreparationFailureIEs->protocolIEs.list.count; i++) {
switch (hoPreparationFailureIEs->protocolIEs.list.array[i]->id) {
case Ngap_ProtocolIE_ID_id_AMF_UE_NGAP_ID: {
if (hoPreparationFailureIEs->protocolIEs.list.array[i]->criticality ==
Ngap_Criticality_ignore &&
hoPreparationFailureIEs->protocolIEs.list.array[i]->value.present ==
Ngap_HandoverPreparationFailureIEs__value_PR_AMF_UE_NGAP_ID) {
amfUeNgapId = new AMF_UE_NGAP_ID();
if (!amfUeNgapId->decodefromAMF_UE_NGAP_ID(
hoPreparationFailureIEs->protocolIEs.list.array[i]
->value.choice.AMF_UE_NGAP_ID)) {
Logger::ngap().error("Decoded NGAP AMF_UE_NGAP_ID IE error");
return false;
}
} else {
Logger::ngap().error("Decoded NGAP AMF_UE_NGAP_ID IE error");
return false;
}
} break;
case Ngap_ProtocolIE_ID_id_RAN_UE_NGAP_ID: {
if (hoPreparationFailureIEs->protocolIEs.list.array[i]->criticality ==
Ngap_Criticality_ignore &&
hoPreparationFailureIEs->protocolIEs.list.array[i]->value.present ==
Ngap_HandoverPreparationFailureIEs__value_PR_RAN_UE_NGAP_ID) {
ranUeNgapId = new RAN_UE_NGAP_ID();
if (!ranUeNgapId->decodefromRAN_UE_NGAP_ID(
hoPreparationFailureIEs->protocolIEs.list.array[i]
->value.choice.RAN_UE_NGAP_ID)) {
Logger::ngap().error("Decoded NGAP RAN_UE_NGAP_ID IE error");
return false;
}
} else {
Logger::ngap().error("Decoded NGAP RAN_UE_NGAP_ID IE error");
return false;
}
} break;
case Ngap_ProtocolIE_ID_id_Cause: {
if (hoPreparationFailureIEs->protocolIEs.list.array[i]->criticality ==
Ngap_Criticality_ignore &&
hoPreparationFailureIEs->protocolIEs.list.array[i]->value.present ==
Ngap_HandoverPreparationFailureIEs__value_PR_Cause) {
cause = new Cause();
if (!cause->decodefromCause(
&hoPreparationFailureIEs->protocolIEs.list.array[i]
->value.choice.Cause)) {
Logger::ngap().error("Decoded NGAP Cause IE error");
return false;
}
} else {
Logger::ngap().error("Decoded NGAP Cause IE error");
return false;
}
} break;
case Ngap_ProtocolIE_ID_id_CriticalityDiagnostics: {
if (hoPreparationFailureIEs->protocolIEs.list.array[i]->criticality ==
Ngap_Criticality_ignore &&
hoPreparationFailureIEs->protocolIEs.list.array[i]->value.present ==
Ngap_HandoverPreparationFailureIEs__value_PR_CriticalityDiagnostics) {
} else {
Logger::ngap().error("Decoded NGAP CriticalityDiagnostics IE error");
return false;
}
} break;
default: {
Logger::ngap().error("Decoded NGAP message PDU error");
return false;
}
}
}
return true;
}
int HandoverPreparationFailure::encode2buffer(uint8_t* buf, int buf_size) {
asn_fprint(stderr, &asn_DEF_Ngap_NGAP_PDU, hoPreparationFailurePdu);
asn_enc_rval_t er = aper_encode_to_buffer(
&asn_DEF_Ngap_NGAP_PDU, NULL, hoPreparationFailurePdu, buf, buf_size);
cout << "er.encoded(" << er.encoded << ")" << endl;
return er.encoded;
}
void HandoverPreparationFailure::setMessageType() {
if (!hoPreparationFailurePdu)
hoPreparationFailurePdu =
(Ngap_NGAP_PDU_t*) calloc(1, sizeof(Ngap_NGAP_PDU_t));
MessageType hoPreparationFailureMessageTypeIE;
hoPreparationFailureMessageTypeIE.setProcedureCode(
Ngap_ProcedureCode_id_HandoverPreparation);
hoPreparationFailureMessageTypeIE.setTypeOfMessage(
Ngap_NGAP_PDU_PR_unsuccessfulOutcome);
hoPreparationFailureMessageTypeIE.setCriticality(Ngap_Criticality_reject);
hoPreparationFailureMessageTypeIE.setValuePresent(
Ngap_UnsuccessfulOutcome__value_PR_HandoverPreparationFailure);
if (hoPreparationFailureMessageTypeIE.getProcedureCode() ==
Ngap_ProcedureCode_id_HandoverPreparation &&
hoPreparationFailureMessageTypeIE.getTypeOfMessage() ==
Ngap_NGAP_PDU_PR_unsuccessfulOutcome) {
hoPreparationFailureMessageTypeIE.encode2pdu(hoPreparationFailurePdu);
hoPreparationFailureIEs =
&(hoPreparationFailurePdu->choice.unsuccessfulOutcome->value.choice
.HandoverPreparationFailure);
} else {
Logger::ngap().warn(
"This information doesn't refer to HandoverPreparationFailure message");
}
}
void HandoverPreparationFailure::setAmfUeNgapId(unsigned long id) {
if (!amfUeNgapId) amfUeNgapId = new AMF_UE_NGAP_ID();
amfUeNgapId->setAMF_UE_NGAP_ID(id);
Ngap_HandoverPreparationFailureIEs_t* ie =
(Ngap_HandoverPreparationFailureIEs_t*) calloc(
1, sizeof(Ngap_HandoverPreparationFailureIEs_t));
ie->id = Ngap_ProtocolIE_ID_id_AMF_UE_NGAP_ID;
ie->criticality = Ngap_Criticality_ignore;
ie->value.present =
Ngap_HandoverPreparationFailureIEs__value_PR_AMF_UE_NGAP_ID;
int ret = amfUeNgapId->encode2AMF_UE_NGAP_ID(ie->value.choice.AMF_UE_NGAP_ID);
if (!ret) {
Logger::ngap().error("Encode AMF_UE_NGAP_ID IE error");
free_wrapper((void**) &ie);
return;
}
ret = ASN_SEQUENCE_ADD(&hoPreparationFailureIEs->protocolIEs.list, ie);
if (ret != 0) Logger::ngap().error("Encode AMF_UE_NGAP_ID IE error");
// free_wrapper((void**) &ie);
}
void HandoverPreparationFailure::setRanUeNgapId(uint32_t ran_ue_ngap_id) {
if (!ranUeNgapId) ranUeNgapId = new RAN_UE_NGAP_ID();
ranUeNgapId->setRanUeNgapId(ran_ue_ngap_id);
Ngap_HandoverPreparationFailureIEs_t* ie =
(Ngap_HandoverPreparationFailureIEs_t*) calloc(
1, sizeof(Ngap_HandoverPreparationFailureIEs_t));
ie->id = Ngap_ProtocolIE_ID_id_RAN_UE_NGAP_ID;
ie->criticality = Ngap_Criticality_reject;
ie->value.present =
Ngap_HandoverPreparationFailureIEs__value_PR_RAN_UE_NGAP_ID;
int ret = ranUeNgapId->encode2RAN_UE_NGAP_ID(ie->value.choice.RAN_UE_NGAP_ID);
if (!ret) {
Logger::ngap().error("Encode RAN_UE_NGAP_ID IE error");
free_wrapper((void**) &ie);
return;
}
ret = ASN_SEQUENCE_ADD(&hoPreparationFailureIEs->protocolIEs.list, ie);
if (ret != 0) Logger::ngap().error("Encode RAN_UE_NGAP_ID IE error");
// free_wrapper((void**) &ie);
}
void HandoverPreparationFailure::setCause(
Ngap_Cause_PR m_causePresent, long value) //
{
if (!cause) cause = new Cause;
Ngap_HandoverPreparationFailureIEs_t* ie =
(Ngap_HandoverPreparationFailureIEs_t*) calloc(
1, sizeof(Ngap_HandoverPreparationFailureIEs_t));
ie->id = Ngap_ProtocolIE_ID_id_Cause;
ie->criticality = Ngap_Criticality_ignore;
ie->value.present = Ngap_HandoverPreparationFailureIEs__value_PR_Cause;
cause->setChoiceOfCause(m_causePresent);
if (m_causePresent != Ngap_Cause_PR_NOTHING) cause->setValue(value);
cause->encode2Cause(&(ie->value.choice.Cause));
int ret = ASN_SEQUENCE_ADD(&hoPreparationFailureIEs->protocolIEs.list, ie);
if (ret != 0) Logger::ngap().error("Encode Cause IE error");
// free_wrapper((void**) &ie);
}
Ngap_Cause_PR HandoverPreparationFailure::getChoiceOfCause() const {
if (cause)
return cause->getChoiceOfCause();
else
return Ngap_Cause_PR();
}
} // namespace ngap
/*
* Licensed to the OpenAirInterface (OAI) Software Alliance under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The OpenAirInterface Software Alliance licenses this file to You under
* the OAI Public License, Version 1.1 (the "License"); you may not use this
* file except in compliance with the License. You may obtain a copy of the
* License at
*
* http://www.openairinterface.org/?page_id=698
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*-------------------------------------------------------------------------------
* For more information about the OpenAirInterface (OAI) Software Alliance:
* contact@openairinterface.org
*/
#ifndef _HANDOVER_PREPARATION_FAILURE_H_
#define _HANDOVER_PREPARATION_FAILURE_H_
#include "AMF-UE-NGAP-ID.hpp"
#include "Cause.hpp"
#include "MessageType.hpp"
#include "NgapIEsStruct.hpp"
#include "RAN-UE-NGAP-ID.hpp"
extern "C" {
#include "Ngap_NGAP-PDU.h"
#include "Ngap_ProtocolIE-Field.h"
}
namespace ngap {
class HandoverPreparationFailure {
public:
HandoverPreparationFailure();
virtual ~HandoverPreparationFailure();
void setMessageType(); // Initialize the PDU and populate the MessageType;
void setAmfUeNgapId(unsigned long id); // 40 bits
unsigned long getAmfUeNgapId() const;
void setRanUeNgapId(uint32_t id); // 32 bits
uint32_t getRanUeNgapId() const;
int encode2buffer(uint8_t* buf, int buf_size);
bool decodefrompdu(Ngap_NGAP_PDU_t* ngap_msg_pdu);
void getCause(Cause& cause) const;
void setCause(Ngap_Cause_PR m_causePresent, long value = 0);
Ngap_Cause_PR getChoiceOfCause() const;
private:
Ngap_NGAP_PDU_t* hoPreparationFailurePdu;
Ngap_HandoverPreparationFailure_t* hoPreparationFailureIEs;
AMF_UE_NGAP_ID* amfUeNgapId;
RAN_UE_NGAP_ID* ranUeNgapId;
Cause* cause;
Ngap_CriticalityDiagnostics_t* CriticalityDiagnostics;
};
} // namespace ngap
#endif
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