Add NGAP Handover Command decoder and RRC handler on source gNB
* add NG Handover Command message decoder * process in RRC: encode RRCReconfiguration message from the received HandoverCommandMessage * trigger RRCReconfiguration for handover Co-authored-by: batuhan duyuler <batuhan.duyuler@firecell.io>
This commit is contained in:
co-authored by
batuhan duyuler
parent
6fd02ee7e8
commit
f66524879d
@@ -85,6 +85,7 @@ MESSAGE_DEF(NGAP_PDUSESSION_MODIFY_REQ , MESSAGE_PRIORITY_MED, ngap_pd
|
||||
MESSAGE_DEF(NGAP_PDUSESSION_RELEASE_COMMAND , MESSAGE_PRIORITY_MED, ngap_pdusession_release_command_t , ngap_pdusession_release_command)
|
||||
MESSAGE_DEF(NGAP_UE_CONTEXT_RELEASE_COMMAND, MESSAGE_PRIORITY_MED, ngap_ue_release_command_t , ngap_ue_release_command)
|
||||
MESSAGE_DEF(NGAP_HANDOVER_REQUEST, MESSAGE_PRIORITY_MED, ngap_handover_request_t, ngap_handover_request)
|
||||
MESSAGE_DEF(NGAP_HANDOVER_COMMAND, MESSAGE_PRIORITY_MED, ngap_handover_command_t, ngap_handover_command)
|
||||
|
||||
/* NGAP <-> RRC messages (can be initiated either by MME or gNB) */
|
||||
MESSAGE_DEF(NGAP_UE_CONTEXT_RELEASE_REQ , MESSAGE_PRIORITY_MED, ngap_ue_release_req_t , ngap_ue_release_req)
|
||||
|
||||
@@ -69,6 +69,7 @@
|
||||
#define NGAP_HANDOVER_FAILURE(mSGpTR) (mSGpTR)->ittiMsg.ngap_handover_failure
|
||||
#define NGAP_HANDOVER_REQUEST(mSGpTR) (mSGpTR)->ittiMsg.ngap_handover_request
|
||||
#define NGAP_HANDOVER_REQUEST_ACKNOWLEDGE(mSGpTR) (mSGpTR)->ittiMsg.ngap_handover_request_ack
|
||||
#define NGAP_HANDOVER_COMMAND(mSGpTR) (mSGpTR)->ittiMsg.ngap_handover_command
|
||||
|
||||
#define NGAP_UE_CONTEXT_RELEASE_REQ(mSGpTR) (mSGpTR)->ittiMsg.ngap_ue_release_req
|
||||
#define NGAP_PDUSESSION_RELEASE_COMMAND(mSGpTR) (mSGpTR)->ittiMsg.ngap_pdusession_release_command
|
||||
@@ -648,6 +649,37 @@ typedef struct {
|
||||
byte_array_t target2source;
|
||||
} ngap_handover_request_ack_t;
|
||||
|
||||
/* 9.3.4.10 3GPP TS 38.413 */
|
||||
typedef struct {
|
||||
// QoS Flow to be Forwarded List
|
||||
uint8_t nb_of_qos_flow;
|
||||
pdusession_associate_qosflow_t qos_setup_list[QOSFLOW_MAX_VALUE];
|
||||
// UL Forwarding UP TNL Information
|
||||
uint32_t gtp_teid;
|
||||
transport_layer_addr_t gNB_addr;
|
||||
} ho_command_transfer_t;
|
||||
|
||||
typedef struct {
|
||||
// PDU Session ID (M)
|
||||
uint8_t pdusession_id;
|
||||
// Handover Command Transfer (M)
|
||||
ho_command_transfer_t ho_command_transfer;
|
||||
} pdusession_resource_handover_t;
|
||||
|
||||
typedef struct {
|
||||
// AMF UE NGAP ID
|
||||
uint64_t amf_ue_ngap_id;
|
||||
// RAN UE NGAP ID
|
||||
uint32_t gNB_ue_ngap_id;
|
||||
// Handover Type
|
||||
ho_type_t handoverType;
|
||||
// PDU Session Resource Handover List
|
||||
uint8_t nb_of_pdusessions;
|
||||
pdusession_resource_handover_t pdu_sessions[NGAP_MAX_PDU_SESSION];
|
||||
// Target to Source Transparent Container
|
||||
byte_array_t handoverCommand;
|
||||
} ngap_handover_command_t;
|
||||
|
||||
typedef struct ngap_ue_cap_info_ind_s {
|
||||
uint32_t gNB_ue_ngap_id;
|
||||
byte_array_t ue_radio_cap;
|
||||
|
||||
@@ -64,6 +64,10 @@
|
||||
#include "NR_LogicalChannelConfig.h"
|
||||
#include "NR_PDCP-Config.h"
|
||||
#include "NR_MAC-CellGroupConfig.h"
|
||||
#include "NR_HandoverPreparationInformation.h"
|
||||
#include "NR_HandoverCommand.h"
|
||||
#include "NR_HandoverCommand-IEs.h"
|
||||
#include "NR_AS-Config.h"
|
||||
#include "NR_SecurityModeCommand.h"
|
||||
#include "NR_CipheringAlgorithm.h"
|
||||
#include "NR_RRCReconfiguration-IEs.h"
|
||||
@@ -1221,6 +1225,41 @@ void fill_removal_lists_from_source_measConfig(NR_MeasConfig_t *currentMC, byte_
|
||||
}
|
||||
}
|
||||
|
||||
int doRRCReconfiguration_from_HandoverCommand(byte_array_t *ba, const byte_array_t handoverCommand)
|
||||
{
|
||||
// Decode Handover Command
|
||||
NR_HandoverCommand_t *hoCommand = NULL;
|
||||
asn_dec_rval_t dec_rval = uper_decode_complete(NULL, &asn_DEF_NR_HandoverCommand, (void **)&hoCommand, handoverCommand.buf, handoverCommand.len);
|
||||
|
||||
if (dec_rval.code != RC_OK && dec_rval.consumed == 0) {
|
||||
LOG_E(NR_RRC, "Can not decode Handover Command!\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
// Prepare DL DCCH message for RRCReconfiguration
|
||||
NR_DL_DCCH_Message_t dl_dcch_msg = {0};
|
||||
asn_enc_rval_t enc_rval;
|
||||
dl_dcch_msg.message.present = NR_DL_DCCH_MessageType_PR_c1;
|
||||
asn1cCalloc(dl_dcch_msg.message.choice.c1, c1);
|
||||
c1->present = NR_DL_DCCH_MessageType__c1_PR_rrcReconfiguration;
|
||||
asn1cCalloc(c1->choice.rrcReconfiguration, rrcReconf);
|
||||
|
||||
// Decode RRCReconfiguration from handoverCommandMessage
|
||||
OCTET_STRING_t *ho = &hoCommand->criticalExtensions.choice.c1->choice.handoverCommand->handoverCommandMessage;
|
||||
uper_decode_complete(NULL, &asn_DEF_NR_RRCReconfiguration, (void **)&rrcReconf, ho->buf, ho->size);
|
||||
if (LOG_DEBUGFLAG(DEBUG_ASN1))
|
||||
xer_fprint(stdout, &asn_DEF_NR_DL_DCCH_Message, (void *)&dl_dcch_msg);
|
||||
|
||||
// Encode DL DCCH message in buffer
|
||||
enc_rval = uper_encode_to_buffer(&asn_DEF_NR_DL_DCCH_Message, NULL, &dl_dcch_msg, ba->buf, ba->len);
|
||||
AssertFatal(enc_rval.encoded > 0, "ASN1 message encoding failed (%s, %lu)!\n", enc_rval.failed_type->name, enc_rval.encoded);
|
||||
|
||||
ASN_STRUCT_FREE_CONTENTS_ONLY(asn_DEF_NR_DL_DCCH_Message, &dl_dcch_msg);
|
||||
ASN_STRUCT_FREE(asn_DEF_NR_HandoverCommand, hoCommand);
|
||||
|
||||
return ((enc_rval.encoded + 7) / 8);
|
||||
}
|
||||
|
||||
byte_array_t get_HandoverCommandMessage(nr_rrc_reconfig_param_t *params)
|
||||
{
|
||||
// Encode RRCReconfiguration to buffer
|
||||
|
||||
@@ -165,5 +165,6 @@ int do_NR_Paging(uint8_t Mod_id, uint8_t *buffer, uint32_t tmsi);
|
||||
byte_array_t get_HandoverPreparationInformation(nr_rrc_reconfig_param_t *params, int scell_pci);
|
||||
byte_array_t get_HandoverCommandMessage(nr_rrc_reconfig_param_t *params);
|
||||
void fill_removal_lists_from_source_measConfig(NR_MeasConfig_t *measConfig, byte_array_t prep_info);
|
||||
int doRRCReconfiguration_from_HandoverCommand(byte_array_t *ba, byte_array_t handoverCommand);
|
||||
|
||||
#endif /* __RRC_NR_MESSAGES_ASN1_MSG__H__ */
|
||||
|
||||
@@ -98,6 +98,7 @@
|
||||
#include "NR_DL-DCCH-Message.h"
|
||||
#include "ds/byte_array.h"
|
||||
#include "alg/find.h"
|
||||
#include "NR_HandoverCommand.h"
|
||||
|
||||
#ifdef E2_AGENT
|
||||
#include "openair2/E2AP/RAN_FUNCTION/O-RAN/ran_func_rc_extern.h"
|
||||
@@ -2949,6 +2950,11 @@ void *rrc_gnb_task(void *args_p) {
|
||||
rrc_gNB_free_Handover_Request(&NGAP_HANDOVER_REQUEST(msg_p)); // Free transfered NG message
|
||||
break;
|
||||
|
||||
case NGAP_HANDOVER_COMMAND:
|
||||
rrc_gNB_process_HandoverCommand(RC.nrrrc[instance], &NGAP_HANDOVER_COMMAND(msg_p));
|
||||
rrc_gNB_free_Handover_Command(&NGAP_HANDOVER_COMMAND(msg_p)); // Free transfered NG message
|
||||
break;
|
||||
|
||||
default:
|
||||
LOG_E(NR_RRC, "[gNB %ld] Received unexpected message %s\n", instance, msg_name_p);
|
||||
break;
|
||||
|
||||
@@ -39,6 +39,9 @@
|
||||
#include <arpa/inet.h>
|
||||
#include "E1AP_ConfidentialityProtectionIndication.h"
|
||||
#include "E1AP_IntegrityProtectionIndication.h"
|
||||
#include "NR_UE-CapabilityRAT-ContainerList.h"
|
||||
#include "NR_HandoverCommand.h"
|
||||
#include "NR_HandoverCommand-IEs.h"
|
||||
#include "NGAP_CauseRadioNetwork.h"
|
||||
#include "NGAP_Dynamic5QIDescriptor.h"
|
||||
#include "NGAP_GTPTunnel.h"
|
||||
@@ -1161,6 +1164,31 @@ void rrc_gNB_free_Handover_Request(ngap_handover_request_t *msg)
|
||||
free(msg->mobility_restriction);
|
||||
}
|
||||
|
||||
/** @brief Process NG Handover Command on Source gNB */
|
||||
void rrc_gNB_process_HandoverCommand(gNB_RRC_INST *rrc, const ngap_handover_command_t *msg)
|
||||
{
|
||||
rrc_gNB_ue_context_t *ue_context_p = rrc_gNB_get_ue_context(rrc, msg->gNB_ue_ngap_id);
|
||||
|
||||
if (ue_context_p == NULL) {
|
||||
LOG_W(NR_RRC, "Unknown UE context associated to gNB_ue_ngap_id (%u)\n", msg->gNB_ue_ngap_id);
|
||||
return;
|
||||
}
|
||||
gNB_RRC_UE_t *UE = &ue_context_p->ue_context;
|
||||
|
||||
uint8_t buffer[NR_RRC_BUF_SIZE];
|
||||
byte_array_t ba = {.buf = buffer, .len = sizeof(buffer)};
|
||||
int enc = doRRCReconfiguration_from_HandoverCommand(&ba, msg->handoverCommand);
|
||||
DevAssert(enc > 0);
|
||||
|
||||
rrc_gNB_trigger_reconfiguration_for_handover(rrc, UE, buffer, enc);
|
||||
LOG_A(NR_RRC, "Send reconfiguration (HO Command) to UE %u/RNTI %04x\n", UE->rrc_ue_id, UE->rnti);
|
||||
}
|
||||
|
||||
void rrc_gNB_free_Handover_Command(ngap_handover_command_t *msg)
|
||||
{
|
||||
free_byte_array(msg->handoverCommand);
|
||||
}
|
||||
|
||||
/*
|
||||
* Process the NG command NGAP_UE_CONTEXT_RELEASE_COMMAND, sent by AMF.
|
||||
* The gNB should remove all pdu session, NG context, and other context of the UE.
|
||||
|
||||
@@ -101,4 +101,7 @@ void rrc_gNB_free_Handover_Request(ngap_handover_request_t *msg);
|
||||
|
||||
void rrc_gNB_send_NGAP_HANDOVER_REQUEST_ACKNOWLEDGE(gNB_RRC_INST *rrc, gNB_RRC_UE_t *UE, byte_array_t ho_command);
|
||||
|
||||
void rrc_gNB_process_HandoverCommand(gNB_RRC_INST *rrc, const ngap_handover_command_t *msg);
|
||||
void rrc_gNB_free_Handover_Command(ngap_handover_command_t *msg);
|
||||
|
||||
#endif
|
||||
|
||||
@@ -231,7 +231,8 @@ static void rrc_deliver_ue_ctxt_modif_req(void *deliver_pdu_data, ue_id_t ue_id,
|
||||
data->modification_req->rrc_container = &ba;
|
||||
data->rrc->mac_rrc.ue_context_modification_request(data->assoc_id, data->modification_req);
|
||||
}
|
||||
static void rrc_gNB_trigger_reconfiguration_for_handover(gNB_RRC_INST *rrc, gNB_RRC_UE_t *ue, uint8_t *rrc_reconf, int rrc_reconf_len)
|
||||
|
||||
void rrc_gNB_trigger_reconfiguration_for_handover(gNB_RRC_INST *rrc, gNB_RRC_UE_t *ue, uint8_t *rrc_reconf, int rrc_reconf_len)
|
||||
{
|
||||
f1_ue_data_t ue_data = cu_get_f1_ue_data(ue->rrc_ue_id);
|
||||
|
||||
|
||||
@@ -89,4 +89,6 @@ void nr_rrc_trigger_n2_ho(gNB_RRC_INST *rrc,
|
||||
int serving_pci,
|
||||
const nr_neighbour_cell_t *neighbour_config);
|
||||
|
||||
void rrc_gNB_trigger_reconfiguration_for_handover(gNB_RRC_INST *rrc, gNB_RRC_UE_t *ue, uint8_t *rrc_reconf, int rrc_reconf_len);
|
||||
|
||||
#endif /* RRC_GNB_MOBILITY_H_ */
|
||||
|
||||
@@ -997,6 +997,60 @@ static int ngap_gNB_handle_pdusession_setup_request(sctp_assoc_t assoc_id, uint3
|
||||
return 0;
|
||||
}
|
||||
|
||||
/** @brief Handler for the NG Handover Command
|
||||
* AMF -> source NG-RAN */
|
||||
static int ngap_gNB_handle_handover_command(sctp_assoc_t assoc_id, uint32_t stream, NGAP_NGAP_PDU_t *pdu)
|
||||
{
|
||||
NGAP_INFO("Received NG Handover Command\n");
|
||||
ngap_gNB_amf_data_t *amf_desc_p = NULL;
|
||||
DevAssert(pdu != NULL);
|
||||
|
||||
if ((amf_desc_p = ngap_gNB_get_AMF(NULL, assoc_id, 0)) == NULL) {
|
||||
NGAP_ERROR(
|
||||
"[SCTP %u] Received Handover Command for non "
|
||||
"existing AMF context\n",
|
||||
assoc_id);
|
||||
return -1;
|
||||
}
|
||||
|
||||
MessageDef *message_p = itti_alloc_new_message(TASK_NGAP, 0, NGAP_HANDOVER_COMMAND);
|
||||
ngap_handover_command_t *msg = &NGAP_HANDOVER_COMMAND(message_p);
|
||||
memset(msg, 0, sizeof(*msg));
|
||||
if (decode_ng_handover_command(msg, pdu) < 0) {
|
||||
NGAP_ERROR("Failed to decode NG Handover Command");
|
||||
free_ng_handover_command(msg);
|
||||
itti_free(TASK_NGAP, message_p);
|
||||
return -1;
|
||||
}
|
||||
|
||||
ngap_gNB_ue_context_t *ue_desc_p = ngap_get_ue_context(msg->gNB_ue_ngap_id);
|
||||
if (!ue_desc_p) {
|
||||
NGAP_ERROR(
|
||||
"[SCTP %u] Received HO Command Msg for non existing UE context (gNB_ue_ngap_id %d) \n",
|
||||
assoc_id,
|
||||
msg->gNB_ue_ngap_id);
|
||||
free_ng_handover_command(msg);
|
||||
itti_free(TASK_NGAP, message_p);
|
||||
return -1;
|
||||
}
|
||||
|
||||
ue_desc_p->rx_stream = stream;
|
||||
|
||||
if (ue_desc_p->amf_ue_ngap_id != msg->amf_ue_ngap_id) {
|
||||
NGAP_ERROR("UE context amf_ue_ngap_id is different form that of the message (%ld != %ld)",
|
||||
ue_desc_p->amf_ue_ngap_id,
|
||||
msg->amf_ue_ngap_id);
|
||||
free_ng_handover_command(msg);
|
||||
itti_free(TASK_NGAP, message_p);
|
||||
return -1;
|
||||
}
|
||||
|
||||
NGAP_DEBUG("Handover Command is parsed with a size of: %ld. Sending to RRC GNB!\n", msg->handoverCommand.len);
|
||||
itti_send_msg_to_task(TASK_RRC_GNB, amf_desc_p->ngap_gNB_instance->instance, message_p);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int ngap_gNB_handle_paging(sctp_assoc_t assoc_id, uint32_t stream, NGAP_NGAP_PDU_t *pdu)
|
||||
{
|
||||
ngap_gNB_amf_data_t *amf_desc_p = NULL;
|
||||
@@ -1338,7 +1392,7 @@ const ngap_message_decoded_callback ngap_messages_callback[][3] = {
|
||||
{ngap_gNB_handle_error_indication, 0, 0}, /* ErrorIndication */
|
||||
{0, 0, 0}, /* HandoverCancel */
|
||||
{0, 0, 0}, /* HandoverNotification */
|
||||
{0, 0, 0}, /* HandoverPreparation */
|
||||
{0, ngap_gNB_handle_handover_command, 0}, /* HandoverPreparation */
|
||||
{ngap_gNB_handle_handover_request, 0, 0}, /* HandoverResourceAllocation */
|
||||
{ngap_gNB_handle_initial_context_request, 0, 0}, /* InitialContextSetup */
|
||||
{0, 0, 0}, /* InitialUEMessage */
|
||||
|
||||
@@ -200,3 +200,11 @@ void tnl_to_bitstring(BIT_STRING_t *out, const transport_layer_addr_t in)
|
||||
out->bits_unused = 0;
|
||||
}
|
||||
}
|
||||
|
||||
void bitstring_to_tnl(transport_layer_addr_t *out, const BIT_STRING_t in)
|
||||
{
|
||||
if (in.size) {
|
||||
memcpy(out->buffer, in.buf, in.size);
|
||||
out->length = in.size;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -50,4 +50,6 @@ void ngap_gNB_prepare_internal_data(void);
|
||||
|
||||
void tnl_to_bitstring(BIT_STRING_t *out, const transport_layer_addr_t in);
|
||||
|
||||
void bitstring_to_tnl(transport_layer_addr_t *out, const BIT_STRING_t in);
|
||||
|
||||
#endif /* NGAP_GNB_MANAGEMENT_PROCEDURES_H_ */
|
||||
|
||||
@@ -472,3 +472,91 @@ void free_ng_handover_req_ack(ngap_handover_request_ack_t *msg)
|
||||
{
|
||||
free_byte_array(msg->target2source);
|
||||
}
|
||||
|
||||
/** @brief Decoder for the NG Handover Command */
|
||||
int decode_ng_handover_command(ngap_handover_command_t *msg, NGAP_NGAP_PDU_t *pdu)
|
||||
{
|
||||
DevAssert(pdu != NULL);
|
||||
NGAP_HandoverCommandIEs_t *ie;
|
||||
NGAP_HandoverCommand_t *container = &pdu->choice.successfulOutcome->value.choice.HandoverCommand;
|
||||
|
||||
// AMF UE NGAP ID (M)
|
||||
NGAP_FIND_PROTOCOLIE_BY_ID(NGAP_HandoverCommandIEs_t, ie, container, NGAP_ProtocolIE_ID_id_AMF_UE_NGAP_ID, true);
|
||||
asn_INTEGER2ulong(&(ie->value.choice.AMF_UE_NGAP_ID), &msg->amf_ue_ngap_id);
|
||||
|
||||
// RAN UE NGAP ID (M)
|
||||
NGAP_FIND_PROTOCOLIE_BY_ID(NGAP_HandoverCommandIEs_t, ie, container, NGAP_ProtocolIE_ID_id_RAN_UE_NGAP_ID, true);
|
||||
msg->gNB_ue_ngap_id = ie->value.choice.RAN_UE_NGAP_ID;
|
||||
|
||||
// Handover Type (M)
|
||||
NGAP_FIND_PROTOCOLIE_BY_ID(NGAP_HandoverCommandIEs_t, ie, container, NGAP_ProtocolIE_ID_id_HandoverType, true);
|
||||
if (ie->value.choice.HandoverType != HANDOVER_TYPE_INTRA5GS) {
|
||||
NGAP_ERROR("Only Intra 5GS Handover is supported at the moment!\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
// PDU Session Resource Handover List (O)
|
||||
NGAP_FIND_PROTOCOLIE_BY_ID(NGAP_HandoverCommandIEs_t, ie, container, NGAP_ProtocolIE_ID_id_HandoverType, false);
|
||||
if (ie != NULL) {
|
||||
msg->nb_of_pdusessions = ie->value.choice.PDUSessionResourceHandoverList.list.count;
|
||||
|
||||
for (int i = 0; i < msg->nb_of_pdusessions; ++i) {
|
||||
NGAP_PDUSessionResourceHandoverItem_t *item = ie->value.choice.PDUSessionResourceHandoverList.list.array[i];
|
||||
|
||||
// PDU Session ID (M)
|
||||
msg->pdu_sessions[i].pdusession_id = item->pDUSessionID;
|
||||
|
||||
// Handover Command Transfer (M)
|
||||
NGAP_HandoverCommandTransfer_t *hoCommandTransfer = NULL;
|
||||
asn_dec_rval_t dec_rval = uper_decode_complete(NULL,
|
||||
&asn_DEF_NGAP_HandoverCommandTransfer,
|
||||
(void **)&hoCommandTransfer,
|
||||
item->handoverCommandTransfer.buf,
|
||||
item->handoverCommandTransfer.size);
|
||||
if (dec_rval.code != RC_OK) {
|
||||
NGAP_ERROR("Failed to decode handoverCommandTransfer\n");
|
||||
continue;
|
||||
}
|
||||
|
||||
// DL Forwarding UP TNL Information (O)
|
||||
if (hoCommandTransfer->dLForwardingUP_TNLInformation) {
|
||||
NGAP_UPTransportLayerInformation_t *up_tnl = hoCommandTransfer->dLForwardingUP_TNLInformation;
|
||||
if (hoCommandTransfer->dLForwardingUP_TNLInformation->present == NGAP_UPTransportLayerInformation_PR_gTPTunnel) {
|
||||
OCTET_STRING_TO_INT32(&(up_tnl->choice.gTPTunnel->gTP_TEID), msg->pdu_sessions[i].ho_command_transfer.gtp_teid);
|
||||
bitstring_to_tnl(&msg->pdu_sessions[i].ho_command_transfer.gNB_addr, up_tnl->choice.gTPTunnel->transportLayerAddress);
|
||||
} else {
|
||||
NGAP_WARN("Missing DL Forwarding UP TNL Information\n");
|
||||
}
|
||||
}
|
||||
ASN_STRUCT_FREE(asn_DEF_NGAP_HandoverCommandTransfer, hoCommandTransfer);
|
||||
}
|
||||
}
|
||||
|
||||
// Target to Source Transparent Container (M)
|
||||
NGAP_FIND_PROTOCOLIE_BY_ID(NGAP_HandoverCommandIEs_t,
|
||||
ie,
|
||||
container,
|
||||
NGAP_ProtocolIE_ID_id_TargetToSource_TransparentContainer,
|
||||
true);
|
||||
NGAP_TargetToSource_TransparentContainer_t *target2source = &(ie->value.choice.TargetToSource_TransparentContainer);
|
||||
NGAP_TargetNGRANNode_ToSourceNGRANNode_TransparentContainer_t *transparentContainer = NULL;
|
||||
asn_dec_rval_t dec_rval = aper_decode_complete(NULL,
|
||||
&asn_DEF_NGAP_TargetNGRANNode_ToSourceNGRANNode_TransparentContainer,
|
||||
(void **)&transparentContainer,
|
||||
target2source->buf,
|
||||
target2source->size);
|
||||
if (dec_rval.code != RC_OK) {
|
||||
NGAP_ERROR("Failed to decode TargetToSource_TransparentContainer\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
msg->handoverCommand = create_byte_array(transparentContainer->rRCContainer.size, transparentContainer->rRCContainer.buf);
|
||||
ASN_STRUCT_FREE(asn_DEF_NGAP_TargetNGRANNode_ToSourceNGRANNode_TransparentContainer, transparentContainer);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
void free_ng_handover_command(ngap_handover_command_t *msg)
|
||||
{
|
||||
free_byte_array(msg->handoverCommand);
|
||||
}
|
||||
|
||||
@@ -31,5 +31,7 @@ NGAP_NGAP_PDU_t *encode_ng_handover_failure(const ngap_handover_failure_t *msg);
|
||||
int decode_ng_handover_request(ngap_handover_request_t *out, const NGAP_NGAP_PDU_t *pdu);
|
||||
NGAP_NGAP_PDU_t *encode_ng_handover_request_ack(ngap_handover_request_ack_t *msg);
|
||||
void free_ng_handover_req_ack(ngap_handover_request_ack_t *msg);
|
||||
int decode_ng_handover_command(ngap_handover_command_t *msg, NGAP_NGAP_PDU_t *pdu);
|
||||
void free_ng_handover_command(ngap_handover_command_t *msg);
|
||||
|
||||
#endif /* NGAP_GNB_MOBILITY_MANAGEMENT_H_ */
|
||||
|
||||
Reference in New Issue
Block a user