forked from acouzens/open5gs
180 lines
7.3 KiB
C
180 lines
7.3 KiB
C
/*
|
|
* Copyright (C) 2019,2020 by Sukchan Lee <acetcom@gmail.com>
|
|
*
|
|
* This file is part of Open5GS.
|
|
*
|
|
* This program is free software: you can redistribute it and/or modify
|
|
* it under the terms of the GNU Affero General Public License as published by
|
|
* the Free Software Foundation, either version 3 of the License, or
|
|
* (at your option) any later version.
|
|
*
|
|
* This program is distributed in the hope that it will be useful,
|
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
* GNU General Public License for more details.
|
|
*
|
|
* You should have received a copy of the GNU General Public License
|
|
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
|
*/
|
|
|
|
#include "ngap-build.h"
|
|
|
|
ogs_pkbuf_t *ngap_build_pdu_session_resource_setup_request_transfer(
|
|
smf_sess_t *sess)
|
|
{
|
|
smf_bearer_t *qos_flow = NULL;
|
|
ogs_ip_t upf_n3_ip;
|
|
|
|
NGAP_PDUSessionResourceSetupRequestTransfer_t message;
|
|
|
|
NGAP_PDUSessionResourceSetupRequestTransferIEs_t *ie = NULL;
|
|
NGAP_PDUSessionAggregateMaximumBitRate_t *PDUSessionAggregateMaximumBitRate;
|
|
NGAP_UPTransportLayerInformation_t *UPTransportLayerInformation = NULL;
|
|
NGAP_GTPTunnel_t *gTPTunnel = NULL;
|
|
NGAP_PDUSessionType_t *PDUSessionType = NULL;
|
|
NGAP_QosFlowSetupRequestList_t *QosFlowSetupRequestList = NULL;
|
|
NGAP_QosFlowSetupRequestItem_t *QosFlowSetupRequestItem = NULL;
|
|
NGAP_QosFlowIdentifier_t *qosFlowIdentifier = NULL;
|
|
NGAP_QosFlowLevelQosParameters_t *qosFlowLevelQosParameters = NULL;
|
|
NGAP_QosCharacteristics_t *qosCharacteristics = NULL;
|
|
NGAP_NonDynamic5QIDescriptor_t *nonDynamic5QI = NULL;
|
|
NGAP_AllocationAndRetentionPriority_t *allocationAndRetentionPriority;
|
|
|
|
ogs_assert(sess);
|
|
qos_flow = smf_default_bearer_in_sess(sess);
|
|
ogs_assert(qos_flow);
|
|
|
|
ogs_debug("PDUSessionResourceSetupRequestTransfer");
|
|
memset(&message, 0, sizeof(NGAP_PDUSessionResourceSetupRequestTransfer_t));
|
|
|
|
if (sess->pdn.ambr.downlink || sess->pdn.ambr.uplink) {
|
|
ie = CALLOC(1,
|
|
sizeof(NGAP_PDUSessionResourceSetupRequestTransferIEs_t));
|
|
ASN_SEQUENCE_ADD(&message.protocolIEs, ie);
|
|
|
|
ie->id = NGAP_ProtocolIE_ID_id_PDUSessionAggregateMaximumBitRate;
|
|
ie->criticality = NGAP_Criticality_reject;
|
|
ie->value.present = NGAP_PDUSessionResourceSetupRequestTransferIEs__value_PR_PDUSessionAggregateMaximumBitRate;
|
|
|
|
PDUSessionAggregateMaximumBitRate =
|
|
&ie->value.choice.PDUSessionAggregateMaximumBitRate;
|
|
|
|
asn_uint642INTEGER(&PDUSessionAggregateMaximumBitRate->
|
|
pDUSessionAggregateMaximumBitRateUL, sess->pdn.ambr.uplink);
|
|
asn_uint642INTEGER(&PDUSessionAggregateMaximumBitRate->
|
|
pDUSessionAggregateMaximumBitRateDL, sess->pdn.ambr.downlink);
|
|
}
|
|
|
|
ie = CALLOC(1, sizeof(NGAP_PDUSessionResourceSetupRequestTransferIEs_t));
|
|
ASN_SEQUENCE_ADD(&message.protocolIEs, ie);
|
|
|
|
ie->id = NGAP_ProtocolIE_ID_id_UL_NGU_UP_TNLInformation;
|
|
ie->criticality = NGAP_Criticality_reject;
|
|
ie->value.present = NGAP_PDUSessionResourceSetupRequestTransferIEs__value_PR_UPTransportLayerInformation;
|
|
|
|
UPTransportLayerInformation = &ie->value.choice.UPTransportLayerInformation;
|
|
|
|
gTPTunnel = CALLOC(1, sizeof(struct NGAP_GTPTunnel));
|
|
UPTransportLayerInformation->present =
|
|
NGAP_UPTransportLayerInformation_PR_gTPTunnel;
|
|
UPTransportLayerInformation->choice.gTPTunnel = gTPTunnel;
|
|
|
|
ogs_sockaddr_to_ip(sess->upf_n3_addr, sess->upf_n3_addr6, &upf_n3_ip);
|
|
ogs_asn_ip_to_BIT_STRING(&upf_n3_ip, &gTPTunnel->transportLayerAddress);
|
|
ogs_asn_uint32_to_OCTET_STRING(sess->upf_n3_teid, &gTPTunnel->gTP_TEID);
|
|
|
|
ie = CALLOC(1, sizeof(NGAP_PDUSessionResourceSetupRequestTransferIEs_t));
|
|
ASN_SEQUENCE_ADD(&message.protocolIEs, ie);
|
|
|
|
ie->id = NGAP_ProtocolIE_ID_id_PDUSessionType;
|
|
ie->criticality = NGAP_Criticality_reject;
|
|
ie->value.present = NGAP_PDUSessionResourceSetupRequestTransferIEs__value_PR_PDUSessionType;
|
|
|
|
PDUSessionType = &ie->value.choice.PDUSessionType;
|
|
|
|
*PDUSessionType = OGS_PDU_SESSION_TYPE_IPV4;
|
|
switch (sess->pdn.pdn_type) {
|
|
case OGS_PDU_SESSION_TYPE_IPV4 :
|
|
*PDUSessionType = NGAP_PDUSessionType_ipv4;
|
|
break;
|
|
case OGS_PDU_SESSION_TYPE_IPV6 :
|
|
*PDUSessionType = NGAP_PDUSessionType_ipv6;
|
|
break;
|
|
case OGS_PDU_SESSION_TYPE_IPV4V6 :
|
|
*PDUSessionType = NGAP_PDUSessionType_ipv4v6;
|
|
break;
|
|
default:
|
|
ogs_fatal("Unknown PDU Session Type [%d]", sess->pdn.pdn_type);
|
|
ogs_assert_if_reached();
|
|
}
|
|
|
|
ie = CALLOC(1, sizeof(NGAP_PDUSessionResourceSetupRequestTransferIEs_t));
|
|
ASN_SEQUENCE_ADD(&message.protocolIEs, ie);
|
|
|
|
ie->id = NGAP_ProtocolIE_ID_id_QosFlowSetupRequestList;
|
|
ie->criticality = NGAP_Criticality_reject;
|
|
ie->value.present = NGAP_PDUSessionResourceSetupRequestTransferIEs__value_PR_QosFlowSetupRequestList;
|
|
|
|
QosFlowSetupRequestList = &ie->value.choice.QosFlowSetupRequestList;
|
|
|
|
QosFlowSetupRequestItem =
|
|
CALLOC(1, sizeof(struct NGAP_QosFlowSetupRequestItem));
|
|
ASN_SEQUENCE_ADD(&QosFlowSetupRequestList->list, QosFlowSetupRequestItem);
|
|
|
|
qosFlowIdentifier = &QosFlowSetupRequestItem->qosFlowIdentifier;
|
|
qosFlowLevelQosParameters =
|
|
&QosFlowSetupRequestItem->qosFlowLevelQosParameters;
|
|
|
|
allocationAndRetentionPriority =
|
|
&qosFlowLevelQosParameters->allocationAndRetentionPriority;
|
|
qosCharacteristics = &qosFlowLevelQosParameters->qosCharacteristics;
|
|
nonDynamic5QI = CALLOC(1, sizeof(struct NGAP_NonDynamic5QIDescriptor));
|
|
qosCharacteristics->choice.nonDynamic5QI = nonDynamic5QI;
|
|
qosCharacteristics->present = NGAP_QosCharacteristics_PR_nonDynamic5QI;
|
|
|
|
*qosFlowIdentifier = qos_flow->qfi;
|
|
|
|
nonDynamic5QI->fiveQI = sess->pdn.qos.qci;
|
|
|
|
allocationAndRetentionPriority->priorityLevelARP =
|
|
sess->pdn.qos.arp.priority_level;;
|
|
if (sess->pdn.qos.arp.pre_emption_capability ==
|
|
OGS_PDN_PRE_EMPTION_CAPABILITY_DISABLED)
|
|
allocationAndRetentionPriority->pre_emptionCapability =
|
|
NGAP_Pre_emptionCapability_shall_not_trigger_pre_emption;
|
|
else
|
|
allocationAndRetentionPriority->pre_emptionCapability =
|
|
NGAP_Pre_emptionCapability_may_trigger_pre_emption;
|
|
|
|
if (sess->pdn.qos.arp.pre_emption_vulnerability ==
|
|
OGS_PDN_PRE_EMPTION_VULNERABILITY_DISABLED)
|
|
allocationAndRetentionPriority->pre_emptionVulnerability =
|
|
NGAP_Pre_emptionVulnerability_not_pre_emptable;
|
|
else
|
|
allocationAndRetentionPriority->pre_emptionVulnerability =
|
|
NGAP_Pre_emptionVulnerability_pre_emptable;
|
|
|
|
return ogs_asn_encode(
|
|
&asn_DEF_NGAP_PDUSessionResourceSetupRequestTransfer, &message);
|
|
}
|
|
|
|
ogs_pkbuf_t *ngap_build_pdu_session_resource_release_command_transfer(
|
|
NGAP_Cause_PR group, long cause)
|
|
{
|
|
NGAP_PDUSessionResourceReleaseCommandTransfer_t message;
|
|
NGAP_Cause_t *Cause = NULL;
|
|
|
|
ogs_debug("PDUSessionResourceReleaseCommandTransfer");
|
|
memset(&message, 0,
|
|
sizeof(NGAP_PDUSessionResourceReleaseCommandTransfer_t));
|
|
|
|
ogs_debug(" Group[%d] Cause[%d]", group, (int)cause);
|
|
|
|
Cause = &message.cause;
|
|
Cause->present = group;
|
|
Cause->choice.radioNetwork = cause;
|
|
|
|
return ogs_asn_encode(
|
|
&asn_DEF_NGAP_PDUSessionResourceReleaseCommandTransfer, &message);
|
|
}
|