Commit a94a7bce authored by Tien-Thinh Nguyen's avatar Tien-Thinh Nguyen

Merge branch 'pdu_session_release_v1.0' into 'develop'

Add PDU Session Release procedure (UE-Initiated)

See merge request oai/oai-cn5g-smf!4
parents 8f42b093 7375681c
......@@ -75,7 +75,7 @@ mkdir build
cd build
cmake ..
make
sudo ./udm-server
sudo ./udm-server -i 172.16.1.103
## Build and launch AMF server
cd /oai-cn5g-smf/src/test/amf
......@@ -83,7 +83,7 @@ mkdir build
cd build
cmake ..
make
sudo ./amf-server
sudo ./amf-server -i 172.16.1.102
## Build and launch AMF client
cd /oai-cn5g-smf/src/test/amf_client
......@@ -91,6 +91,6 @@ mkdir build
cd build
cmake ..
make
./amf-client
./amf-client -i 172.16.1.101
......@@ -82,47 +82,6 @@ typedef struct s_nssai // section 28.4, TS23.003
typedef uint8_t pdu_session_id;
//should move to 24.501
enum pdu_session_type_e {
PDU_SESSION_TYPE_E_UNKNOWN = 0,
PDU_SESSION_TYPE_E_IPV4 = 1,
PDU_SESSION_TYPE_E_IPV6 = 2,
PDU_SESSION_TYPE_E_IPV4V6 = 3,
PDU_SESSION_TYPE_E_UNSTRUCTURED = 4,
PDU_SESSION_TYPE_E_ETHERNET = 5,
PDU_SESSION_TYPE_E_RESERVED = 7,
};
static const std::vector<std::string> pdu_session_type_e2str = { "Error",
"IPV4", "IPV6", "IPV4V6", "UNSTRUCTURED", "ETHERNET", "IPV4V6", "RESERVED" };
typedef struct pdu_session_type_s {
uint8_t pdu_session_type;
pdu_session_type_s()
:
pdu_session_type(PDU_SESSION_TYPE_E_IPV4) {
}
pdu_session_type_s(const uint8_t &p)
:
pdu_session_type(p) {
}
pdu_session_type_s(const struct pdu_session_type_s &p)
:
pdu_session_type(p.pdu_session_type) {
}
bool operator==(const struct pdu_session_type_s &p) const {
return (p.pdu_session_type == pdu_session_type);
}
//------------------------------------------------------------------------------
bool operator==(const pdu_session_type_e &p) const {
return (p == pdu_session_type);
}
//------------------------------------------------------------------------------
const std::string& toString() const {
return pdu_session_type_e2str.at(pdu_session_type);
}
} pdu_session_type_t;
//SMF + AMF + 3GPP TS 29.571 (Common data)
enum class http_response_codes_e {
HTTP_RESPONSE_CODE_OK = 200,
......
/*
* 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
*/
/*! \file 3gpp_29.281.cpp
\brief
\author Lionel Gauthier
\company Eurecom
\email: lionel.gauthier@eurecom.fr
*/
#include "3gpp_29.281.hpp"
#include <string>
#include <string.h>
using namespace gtpv1u;
//------------------------------------------------------------------------------
gtpv1u_ie * gtpv1u_ie::new_gtpv1u_ie_from_stream(std::istream& is) {
gtpv1u_tlv tlv;
tlv.load_from(is);
if (tlv.length) {
switch (tlv.type) {
case GTPU_IE_RECOVERY: {
gtpv1u_recovery_ie *ie = new gtpv1u_recovery_ie(tlv);
ie->load_from(is);
return ie;
}
break;
case GTPU_IE_TUNNEL_ENDPOINT_IDENTIFIER_DATA_I: {
gtpv1u_tunnel_endpoint_identifier_data_i_ie *ie = new gtpv1u_tunnel_endpoint_identifier_data_i_ie(tlv);
ie->load_from(is);
return ie;
}
break;
case GTPU_IE_GTP_U_PEER_ADDRESS: {
gtpv1u_gtp_u_peer_address_ie *ie = new gtpv1u_gtp_u_peer_address_ie(tlv);
ie->load_from(is);
return ie;
}
break;
case GTPU_IE_PRIVATE_EXTENSION: {
gtpv1u_private_extension_ie *ie = new gtpv1u_private_extension_ie(tlv);
ie->load_from(is);
return ie;
}
break;
default:
Logger::gtpv1_u().error("Unknown GTP IE type %d (length %d)", tlv.get_type(), tlv.get_length());
return nullptr;
}
} else {
Logger::gtpv1_u().error("GTP IE type %d length %d", tlv.get_type(), tlv.get_length());
return nullptr;
}
}
//------------------------------------------------------------------------------
gtpv1u_msg::gtpv1u_msg(const gtpv1u_echo_request& gtp_ies) : gtpv1u_msg_header() {
ies = {};
set_message_type(GTPU_ECHO_REQUEST);
if (gtp_ies.private_extension.first) {std::shared_ptr<gtpv1u_private_extension_ie> sie(new gtpv1u_private_extension_ie(gtp_ies.private_extension.second)); add_ie(sie);}
}
//------------------------------------------------------------------------------
gtpv1u_msg::gtpv1u_msg(const gtpv1u_echo_response& gtp_ies) : gtpv1u_msg_header() {
ies = {};
set_message_type(GTPU_ECHO_RESPONSE);
if (gtp_ies.recovery.first) {std::shared_ptr<gtpv1u_recovery_ie> sie(new gtpv1u_recovery_ie(gtp_ies.recovery.second)); add_ie(sie);}
if (gtp_ies.private_extension.first) {std::shared_ptr<gtpv1u_private_extension_ie> sie(new gtpv1u_private_extension_ie(gtp_ies.private_extension.second)); add_ie(sie);}
}
//------------------------------------------------------------------------------
gtpv1u_msg::gtpv1u_msg(const gtpv1u_error_indication& gtp_ies) : gtpv1u_msg_header() {
ies = {};
set_message_type(GTPU_ERROR_INDICATION);
if (gtp_ies.tunnel_endpoint_identifier_data_i.first) {std::shared_ptr<gtpv1u_tunnel_endpoint_identifier_data_i_ie> sie(new gtpv1u_tunnel_endpoint_identifier_data_i_ie(gtp_ies.tunnel_endpoint_identifier_data_i.second)); add_ie(sie);}
if (gtp_ies.gtp_u_peer_address.first) {std::shared_ptr<gtpv1u_gtp_u_peer_address_ie> sie(new gtpv1u_gtp_u_peer_address_ie(gtp_ies.gtp_u_peer_address.second)); add_ie(sie);}
if (gtp_ies.private_extension.first) {std::shared_ptr<gtpv1u_private_extension_ie> sie(new gtpv1u_private_extension_ie(gtp_ies.private_extension.second)); add_ie(sie);}
}
This diff is collapsed.
################################################################################
# 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
################################################################################
add_library(GTPV1U STATIC
3gpp_29.281.cpp
gtpv1u.cpp
)
include_directories(${SRC_TOP_DIR}/common)
include_directories(${SRC_TOP_DIR}/common/msg)
include_directories(${SRC_TOP_DIR}/common/utils)
include_directories(${SRC_TOP_DIR}/itti)
include_directories(${SRC_TOP_DIR}/gtpv1u)
include_directories(${SRC_TOP_DIR}/udp)
include_directories(${SRC_TOP_DIR}/../build/ext/spdlog/include)
/*
* 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
*/
/*! \file gtpu.h
* \brief
* \author Lionel Gauthier
* \company Eurecom
* \email: lionel.gauthier@eurecom.fr
*/
#ifndef FILE_GTPU_SEEN
#define FILE_GTPU_SEEN
#include <endian.h>
#include <stdint.h>
struct gtpuhdr
{
#if __BYTE_ORDER == __LITTLE_ENDIAN
unsigned int pn:1;
unsigned int s:1;
unsigned int e:1;
unsigned int spare:1;
unsigned int pt:1;
unsigned int version:3;
#elif __BYTE_ORDER == __BIG_ENDIAN
unsigned int version:3;
unsigned int pt:1;
unsigned int spare:1;
unsigned int e:1;
unsigned int s:1;
unsigned int pn:1;
#else
# error "Please fix <bits/endian.h>"
#endif
// Message Type: This field indicates the type of GTP-U message.
uint8_t message_type;
// Length: This field indicates the length in octets of the payload, i.e. the rest of the packet following the mandatory
// part of the GTP header (that is the first 8 octets). The Sequence Number, the N-PDU Number or any Extension
// headers shall be considered to be part of the payload, i.e. included in the length count.
uint16_t message_length;
// Tunnel Endpoint Identifier (TEID): This field unambiguously identifies a tunnel endpoint in the receiving
// GTP-U protocol entity. The receiving end side of a GTP tunnel locally assigns the TEID value the transmitting
// side has to use. The TEID value shall be assigned in a non-predictable manner for PGW S5/S8/S2a/S2b
// interfaces (see 3GPP TS 33.250 [32]). The TEID shall be used by the receiving entity to find the PDP context,
// except for the following cases:
// -) The Echo Request/Response and Supported Extension Headers notification messages, where the Tunnel
// Endpoint Identifier shall be set to all zeroes
// -) The Error Indication message where the Tunnel Endpoint Identifier shall be set to all zeros.
uint32_t teid;
/*The options start here. */
};
#endif
/*
* 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
*/
/*! \file gtpv1u.cpp
\brief
\author Lionel Gauthier
\company Eurecom
\email: lionel.gauthier@eurecom.fr
*/
#include "common_root_types.h"
#include "conversions.hpp"
#include "gtpu.h"
#include "gtpv1u.hpp"
#include <cstdlib>
#include <sched.h>
using namespace gtpv1u;
using namespace std;
extern itti_mw *itti_inst;
////------------------------------------------------------------------------------
//void udp_server::handle_receive(const int& error, std::size_t bytes_transferred)
//{
// if (!error) {
// Logger::udp().trace( "udp_server::handle_receive on %s:%d from %s:%d",
// socket_.local_endpoint().address().to_string().c_str(), socket_.local_endpoint().port(),
// remote_endpoint_.address().to_string().c_str(), remote_endpoint_.port());
// if (app_) {
// app_->handle_receive(recv_buffer_.data(), bytes_transferred, remote_endpoint_);
// } else {
// Logger::udp().error( "No upper layer configured for handling UDP packet");
// }
// start_receive(app_);
// } else {
// Logger::udp().error( "udp_server::handle_receive err=%s/%d: %s", error.category().name(), error.value(), error.message());
// }
//}
//------------------------------------------------------------------------------
gtpu_l4_stack::gtpu_l4_stack(const struct in_addr& address, const uint16_t port_num, const util::thread_sched_params& sched_params) :
udp_s(udp_server(address, port_num))
{
Logger::gtpv1_u().info( "gtpu_l4_stack created listening to %s:%d", conv::toString(address).c_str(), port_num);
id = 0;
srand (time(NULL));
seq_num = rand() & 0x7FFFFFFF;
restart_counter = 0;
udp_s.start_receive(this, sched_params);
}
//------------------------------------------------------------------------------
gtpu_l4_stack::gtpu_l4_stack(const struct in6_addr& address, const uint16_t port_num, const util::thread_sched_params& sched_params) :
udp_s(udp_server(address, port_num))
{
Logger::gtpv1_u().info( "gtpu_l4_stack created listening to %s:%d", conv::toString(address).c_str(), port_num);
id = 0;
srand (time(NULL));
seq_num = rand() & 0x7FFFFFFF;
restart_counter = 0;
udp_s.start_receive(this, sched_params);
}
//------------------------------------------------------------------------------
gtpu_l4_stack::gtpu_l4_stack(char * address, const uint16_t port_num, const util::thread_sched_params& sched_params) :
udp_s(udp_server(address, port_num))
{
Logger::gtpv1_u().info( "gtpu_l4_stack created listening to %s:%d", address, port_num);
id = 0;
srand (time(NULL));
seq_num = rand() & 0x7FFFFFFF;
restart_counter = 0;
udp_s.start_receive(this, sched_params);
}
//------------------------------------------------------------------------------
uint32_t gtpu_l4_stack::get_next_seq_num() {
seq_num++;
if (seq_num & 0x80000000) {
seq_num = 0;
}
return seq_num;
}
//------------------------------------------------------------------------------
void gtpu_l4_stack::handle_receive(char* recv_buffer, const std::size_t bytes_transferred, const endpoint& r_endpoint)
{
Logger::gtpv1_u().error( "TODO implement in derived class");
}
//------------------------------------------------------------------------------
bool gtpu_l4_stack::check_initial_message_type(const uint8_t initial)
{
switch (initial) {
case GTPU_ECHO_REQUEST:
case GTPU_END_MARKER:
return true;
break;
default:
return false;
}
}
//------------------------------------------------------------------------------
bool gtpu_l4_stack::check_triggered_message_type(const uint8_t initial, const uint8_t triggered)
{
Logger::gtpv1_u().info( "check_triggered_message_type GTPV1-U msg type %d/%d", (int)initial, (int)triggered);
switch (initial) {
case GTPU_ECHO_REQUEST:
if (triggered == GTPU_ECHO_RESPONSE) return true;
return false;
break;
case GTPU_ERROR_INDICATION:
case GTPU_SUPPORTED_EXTENSION_HEADERS_NOTIFICATION:
return true;
break;
default:
return false;
}
}
//------------------------------------------------------------------------------
void gtpu_l4_stack::handle_receive_message_cb(const gtpv1u_msg& msg, const struct sockaddr_storage& r_endpoint, const socklen_t& r_endpoint_addr_len, const task_id_t& task_id, bool &error, uint64_t& gtpc_tx_id)
{
}
//------------------------------------------------------------------------------
void gtpu_l4_stack::send_g_pdu(const struct sockaddr_in& peer_addr, const teid_t teid, const char* payload, const ssize_t payload_len)
{
struct gtpuhdr *gtpuhdr = reinterpret_cast<struct gtpuhdr *>(reinterpret_cast<uintptr_t>(payload) - (uintptr_t)sizeof(struct gtpuhdr));
gtpuhdr->spare = 0;
gtpuhdr->e = 0;
gtpuhdr->s = 0;
gtpuhdr->pn = 0;
gtpuhdr->pt = 1;
gtpuhdr->version = 1;
gtpuhdr->message_type = GTPU_G_PDU;
gtpuhdr->message_length = htobe16(payload_len);
gtpuhdr->teid = htobe32(teid);
udp_s.async_send_to(reinterpret_cast<const char*>(gtpuhdr), payload_len + sizeof(struct gtpuhdr), peer_addr);
}
//------------------------------------------------------------------------------
void gtpu_l4_stack::send_g_pdu(const struct sockaddr_in6& peer_addr, const teid_t teid, const char* payload, const ssize_t payload_len)
{
struct gtpuhdr *gtpuhdr = reinterpret_cast<struct gtpuhdr *>(reinterpret_cast<uintptr_t>(payload) - (uintptr_t)sizeof(struct gtpuhdr));
gtpuhdr->spare = 0;
gtpuhdr->e = 0;
gtpuhdr->s = 0;
gtpuhdr->pn = 0;
gtpuhdr->pt = 1;
gtpuhdr->version = 1;
gtpuhdr->message_type = GTPU_G_PDU;
gtpuhdr->message_length = htobe16(payload_len);
gtpuhdr->teid = htobe32(teid);
udp_s.async_send_to(reinterpret_cast<const char*>(gtpuhdr), payload_len + sizeof(struct gtpuhdr), peer_addr);
}
//------------------------------------------------------------------------------
void gtpu_l4_stack::send_response(const gtpv1u_echo_response& gtp_ies)
{
std::ostringstream oss(std::ostringstream::binary);
gtpv1u_msg msg(gtp_ies);
uint32_t teid = UNASSIGNED_TEID;
if (gtp_ies.get_teid(teid)) {
msg.set_teid(teid);
}
uint16_t sn = 0;
if (gtp_ies.get_sequence_number(sn)) {
msg.set_sequence_number(sn);
}
msg.dump_to(oss);
std::string bstream = oss.str();
udp_s.async_send_to(reinterpret_cast<const char*>(bstream.c_str()), bstream.length(), gtp_ies.r_endpoint);
}
//------------------------------------------------------------------------------
void gtpu_l4_stack::send_indication(const gtpv1u_error_indication& gtp_ies)
{
std::ostringstream oss(std::ostringstream::binary);
gtpv1u_msg msg(gtp_ies);
uint32_t teid = UNASSIGNED_TEID;
if (gtp_ies.get_teid(teid)) {
msg.set_teid(teid);
}
uint16_t sn = 0;
if (gtp_ies.get_sequence_number(sn)) {
msg.set_sequence_number(sn);
}
msg.dump_to(oss);
std::string bstream = oss.str();
udp_s.async_send_to(reinterpret_cast<const char*>(bstream.c_str()), bstream.length(), gtp_ies.r_endpoint);
}
/*
* 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
*/
/*! \file gtpv1u.hpp
\brief
\author Lionel Gauthier
\company Eurecom
\email: lionel.gauthier@eurecom.fr
*/
#ifndef FILE_GTPV1U_HPP_SEEN
#define FILE_GTPV1U_HPP_SEEN
#include "3gpp_29.281.hpp"
#include "itti.hpp"
#include "msg_gtpv1u.hpp"
#include "thread_sched.hpp"
#include "udp.hpp"
#include <iostream>
#include <map>
#include <memory>
#include <stdint.h>
#include <string>
#include <system_error>
#include <thread>
#include <utility>
#include <vector>
namespace gtpv1u {
static const uint16_t default_port = 2152;
class gtpu_l4_stack : public udp_application {
#define GTPV1U_T3_RESPONSE_MS 1000
#define GTPV1U_N3_REQUESTS 5
#define GTPV1U_PROC_TIME_OUT_MS ((GTPV1U_T3_RESPONSE_MS) * (GTPV1U_N3_REQUESTS + 1))
protected:
uint32_t id;
udp_server udp_s;
// seems no need for std::atomic_uint32_t
uint32_t seq_num;
uint32_t restart_counter;
static bool check_initial_message_type(const uint8_t initial);
static bool check_triggered_message_type(const uint8_t initial, const uint8_t triggered);
uint32_t get_next_seq_num();
public:
static const uint8_t version = 1;
gtpu_l4_stack(const struct in_addr& address, const uint16_t port_num, const util::thread_sched_params& sched_params);
gtpu_l4_stack(const struct in6_addr& address, const uint16_t port_num, const util::thread_sched_params& sched_params);
gtpu_l4_stack(char * ip_address, const uint16_t port_num, const util::thread_sched_params& sched_params);
virtual void handle_receive(char* recv_buffer, const std::size_t bytes_transferred, const endpoint& r_endpoint);
void handle_receive_message_cb(const gtpv1u_msg& msg, const struct sockaddr_storage& r_endpoint, const socklen_t& r_endpoint_addr_len, const task_id_t& task_id, bool &error, uint64_t& gtpc_tx_id);
void send_g_pdu(const struct sockaddr_in& peer_addr, const teid_t teid, const char* payload, const ssize_t payload_len);
void send_g_pdu(const struct sockaddr_in6& peer_addr, const teid_t teid, const char* payload, const ssize_t payload_len);
void send_response(const gtpv1u_echo_response& gtp_ies);
void send_indication(const gtpv1u_error_indication& gtp_ies);
};
} // namespace gtpv1u
#endif /* FILE_GTPV1U_HPP_SEEN */
This diff is collapsed.
......@@ -22,7 +22,7 @@
/*
* This file contains NAS header bits format
* Refer TS24.007 TS24.501
* Auther: Puzyu Dukl
* Author: Puzyu Dukl (BUPT), Tien-Thinh NGUYEN (EURECOM)
* Time:
* Email:
*/
......@@ -246,64 +246,6 @@ enum class cause_value_5gsm_e {
CAUSE_100_CONDITIONAL_IE_ERROR = 100,
CAUSE_101_MESSAGE_NOT_COMPATIBLE_WITH_PROTOCOL_STATE = 101,
CAUSE_111_PROTOCOL_ERROR_UNSPECIFIED = 111
/*
Cause #8 – Operator Determined Barring
Cause #26 – Insufficient resources
Cause #27 – Missing or unknown DNN
Cause #28 – Unknown PDU session type
Cause #29 – User authentication or authorization failed
Cause #31 – Request rejected, unspecified
Cause #32 – Service option not supported
Cause #33 – Requested service option not subscribed
Cause #35 – PTI already in use
Cause #36 – Regular deactivation
Cause #38 – Network failure
Cause #39 – Reactivation requested
Cause #41 – Semantic error in the TFT operation
Cause #42 – Syntactical error in the TFT operation
Cause #43 –Invalid PDU session identity
Cause #44 – Semantic errors in packet filter(s)
Cause #45 – Syntactical error in packet filter(s)
Cause #46 –Out of LADN service area
Cause #47 –PTI mismatch
Cause #50 – PDU session type IPv4 only allowed
Cause #51 – PDU session type IPv6 only allowed
Cause #54 –PDU session does not exist
Cause #67 – Insufficient resources for specific slice and DNN
Cause #68 – Not supported SSC mode
Cause #69 –Insufficient resources for specific slice
Cause #70 – Missing or unknown DNN in a slice
Cause #81 – Invalid PTI value
Cause #82 – Maximum data rate per UE for user-plane integrity protection is too low
Cause #83 – Semantic error in the QoS operation
Cause #84 – Syntactical error in the QoS operation
Cause #85 – Invalid mapped EPS bearer identity
//Protocol errors
Cause #95 – Semantically incorrect message
Cause #96 – Invalid mandatory information
Cause #97 – Message type non-existent or not implemented
Cause #98 – Message type not compatible with protocol state
Cause #99 – Information element non-existent or not implemented
Cause #100 – Conditional IE error
Cause #101 – Message not compatible with protocol state
Cause #111 – Protocol error, unspecified
*/
};
enum cause_value_protocol_errors_e {
CAUSE_95_SEMANTICALLY_INCORRECT_MESSAGE = 95
/*
Cause #95 – Semantically incorrect message
Cause #96 – Invalid mandatory information
Cause #97 – Message type non-existent or not implemented
Cause #98 – Message type not compatible with protocol state
Cause #99 – Information element non-existent or not implemented
Cause #100 – Conditional IE error
Cause #101 – Message not compatible with protocol state
Cause #111 – Protocol error, unspecified
*/
};
//The 5GSM sublayer states for PDU session handling in the network
......@@ -348,6 +290,49 @@ enum notification_control_e {
static const std::vector<std::string> notification_control_e2str = { "ERROR",
"REQUESTED", "NOT_REQUESTED" };
//PDU Session Type value
enum pdu_session_type_e {
PDU_SESSION_TYPE_E_UNKNOWN = 0,
PDU_SESSION_TYPE_E_IPV4 = 1,
PDU_SESSION_TYPE_E_IPV6 = 2,
PDU_SESSION_TYPE_E_IPV4V6 = 3,
PDU_SESSION_TYPE_E_UNSTRUCTURED = 4,
PDU_SESSION_TYPE_E_ETHERNET = 5,
PDU_SESSION_TYPE_E_RESERVED = 7,
};
static const std::vector<std::string> pdu_session_type_e2str = { "Error",
"IPV4", "IPV6", "IPV4V6", "UNSTRUCTURED", "ETHERNET", "IPV4V6", "RESERVED" };
typedef struct pdu_session_type_s {
uint8_t pdu_session_type;
pdu_session_type_s()
:
pdu_session_type(PDU_SESSION_TYPE_E_IPV4) {
}
pdu_session_type_s(const uint8_t &p)
:
pdu_session_type(p) {
}
pdu_session_type_s(const struct pdu_session_type_s &p)
:
pdu_session_type(p.pdu_session_type) {
}
bool operator==(const struct pdu_session_type_s &p) const {
return (p.pdu_session_type == pdu_session_type);
}
//------------------------------------------------------------------------------
bool operator==(const pdu_session_type_e &p) const {
return (p == pdu_session_type);
}
//------------------------------------------------------------------------------
const std::string& toString() const {
return pdu_session_type_e2str.at(pdu_session_type);
}
} pdu_session_type_t;
#endif
#endif
......@@ -6,104 +6,105 @@
#include "TLVDecoder.h"
#include "SNSSAI.h"
int encode_snssai ( SNSSAI snssai, uint8_t iei, uint8_t * buffer, uint32_t len )
{
uint32_t encoded = 0;
uint8_t ielen = 0;
uint8_t bitStream = 0;
uint32_t bit32Stream = 0;
CHECK_PDU_POINTER_AND_LENGTH_ENCODER (buffer,((iei > 0) ? SNSSAI_MINIMUM_LENGTH_TLV : SNSSAI_MINIMUM_LENGTH_TLV-1) , len);
if( iei >0 )
{
*buffer=iei;
encoded++;
}
ielen = snssai.len;
*(buffer + encoded) = ielen;
int encode_snssai(SNSSAI snssai, uint8_t iei, uint8_t *buffer, uint32_t len) {
uint32_t encoded = 0;
uint8_t ielen = 0;
uint8_t bitStream = 0;
uint32_t bit32Stream = 0;
CHECK_PDU_POINTER_AND_LENGTH_ENCODER(
buffer,
((iei > 0) ? SNSSAI_MINIMUM_LENGTH_TLV : SNSSAI_MINIMUM_LENGTH_TLV-1),
len);
if (iei > 0) {
*buffer = iei;
encoded++;
}
bitStream = snssai.sst;
ENCODE_U8(buffer+encoded,bitStream,encoded);
if((ielen == SST_AND_SD_LENGHT) || (ielen == SST_AND_SD_AND_MAPPEDHPLMNSST_LENGHT) || (ielen == SST_AND_SD_AND_MAPPEDHPLMNSST_AND_MAPPEDHPLMNSD_LENGHT))
{
bit32Stream = snssai.sd;
ENCODE_U8(buffer+encoded,(uint8_t)bit32Stream,encoded);
ENCODE_U8(buffer+encoded,(uint8_t)(bit32Stream>>8),encoded);
ENCODE_U8(buffer+encoded,(uint8_t)(bit32Stream>>16),encoded);
}
if((ielen == SST_AND_MAPPEDHPLMNSST_LENGHT) || (ielen == SST_AND_SD_AND_MAPPEDHPLMNSST_LENGHT) || (ielen == SST_AND_SD_AND_MAPPEDHPLMNSST_AND_MAPPEDHPLMNSD_LENGHT))
{
bitStream = snssai.mappedhplmnsst;
ENCODE_U8(buffer+encoded,bitStream,encoded);
}
if(ielen == SST_AND_SD_AND_MAPPEDHPLMNSST_AND_MAPPEDHPLMNSD_LENGHT)
{
bit32Stream = snssai.mappedhplmnsd;
ENCODE_U8(buffer+encoded,(uint8_t)bit32Stream,encoded);
ENCODE_U8(buffer+encoded,(uint8_t)(bit32Stream>>8),encoded);
ENCODE_U8(buffer+encoded,(uint8_t)(bit32Stream>>16),encoded);
}
return encoded;
}
ielen = snssai.len;
*(buffer + encoded) = ielen;
encoded++;
int decode_snssai ( SNSSAI * snssai, uint8_t iei, uint8_t * buffer, uint32_t len )
{
int decoded=0;
uint8_t ielen=0;
uint8_t bitStream = 0;
uint32_t bit32Stream = 0;
bitStream = snssai.sst;
ENCODE_U8(buffer + encoded, bitStream, encoded);
if ((ielen == SST_AND_SD_LENGTH)
|| (ielen == SST_AND_SD_AND_MAPPEDHPLMNSST_LENGTH)
|| (ielen == SST_AND_SD_AND_MAPPEDHPLMNSST_AND_MAPPEDHPLMNSD_LENGTH)) {
bit32Stream = snssai.sd;
ENCODE_U8(buffer + encoded, (uint8_t )bit32Stream, encoded);
ENCODE_U8(buffer + encoded, (uint8_t )(bit32Stream >> 8), encoded);
ENCODE_U8(buffer + encoded, (uint8_t )(bit32Stream >> 16), encoded);
}
if ((ielen == SST_AND_MAPPEDHPLMNSST_LENGTH)
|| (ielen == SST_AND_SD_AND_MAPPEDHPLMNSST_LENGTH)
|| (ielen == SST_AND_SD_AND_MAPPEDHPLMNSST_AND_MAPPEDHPLMNSD_LENGTH)) {
bitStream = snssai.mappedhplmnsst;
ENCODE_U8(buffer + encoded, bitStream, encoded);
}
if (ielen == SST_AND_SD_AND_MAPPEDHPLMNSST_AND_MAPPEDHPLMNSD_LENGTH) {
bit32Stream = snssai.mappedhplmnsd;
ENCODE_U8(buffer + encoded, (uint8_t )bit32Stream, encoded);
ENCODE_U8(buffer + encoded, (uint8_t )(bit32Stream >> 8), encoded);
ENCODE_U8(buffer + encoded, (uint8_t )(bit32Stream >> 16), encoded);
}
return encoded;
}
if (iei > 0)
{
CHECK_IEI_DECODER (iei, *buffer);
decoded++;
}
int decode_snssai(SNSSAI *snssai, uint8_t iei, uint8_t *buffer, uint32_t len) {
int decoded = 0;
uint8_t ielen = 0;
uint8_t bitStream = 0;
uint32_t bit32Stream = 0;
ielen = *(buffer + decoded);
if (iei > 0) {
CHECK_IEI_DECODER(iei, *buffer);
decoded++;
CHECK_LENGTH_DECODER (len - decoded, ielen);
snssai->len = ielen;
DECODE_U8(buffer+decoded,bitStream,decoded);
snssai->sst = bitStream;
if((ielen == SST_AND_SD_LENGHT) || (ielen == SST_AND_SD_AND_MAPPEDHPLMNSST_LENGHT) || (ielen == SST_AND_SD_AND_MAPPEDHPLMNSST_AND_MAPPEDHPLMNSD_LENGHT))
{
DECODE_U8(buffer+decoded,bitStream,decoded);
bit32Stream = (uint32_t)(bitStream&0Xff);
DECODE_U8(buffer+decoded,bitStream,decoded);
bit32Stream |= (uint32_t)((bitStream<<8)&0xff00);
DECODE_U8(buffer+decoded,bitStream,decoded);
bit32Stream |= (uint32_t)((bitStream<<16)&0xff0000);
snssai->sd = bit32Stream;
}
if((ielen == SST_AND_MAPPEDHPLMNSST_LENGHT) || (ielen == SST_AND_SD_AND_MAPPEDHPLMNSST_LENGHT) || (ielen == SST_AND_SD_AND_MAPPEDHPLMNSST_AND_MAPPEDHPLMNSD_LENGHT))
{
DECODE_U8(buffer+decoded,bitStream,decoded);
snssai->mappedhplmnsst = bitStream;
}
if(ielen == SST_AND_SD_AND_MAPPEDHPLMNSST_AND_MAPPEDHPLMNSD_LENGHT)
{
DECODE_U8(buffer+decoded,bitStream,decoded);
bit32Stream = (uint32_t)(bitStream&0Xff);
DECODE_U8(buffer+decoded,bitStream,decoded);
bit32Stream |= (uint32_t)((bitStream<<8)&0xff00);
DECODE_U8(buffer+decoded,bitStream,decoded);
bit32Stream |= (uint32_t)((bitStream<<16)&0xff0000);
snssai->mappedhplmnsd = bit32Stream;
}
return decoded;
}
ielen = *(buffer + decoded);
decoded++;
CHECK_LENGTH_DECODER(len - decoded, ielen);
snssai->len = ielen;
DECODE_U8(buffer + decoded, bitStream, decoded);
snssai->sst = bitStream;
if ((ielen == SST_AND_SD_LENGTH)
|| (ielen == SST_AND_SD_AND_MAPPEDHPLMNSST_LENGTH)
|| (ielen == SST_AND_SD_AND_MAPPEDHPLMNSST_AND_MAPPEDHPLMNSD_LENGTH)) {
DECODE_U8(buffer + decoded, bitStream, decoded);
bit32Stream = (uint32_t) (bitStream & 0Xff);
DECODE_U8(buffer + decoded, bitStream, decoded);
bit32Stream |= (uint32_t) ((bitStream << 8) & 0xff00);
DECODE_U8(buffer + decoded, bitStream, decoded);
bit32Stream |= (uint32_t) ((bitStream << 16) & 0xff0000);
snssai->sd = bit32Stream;
}
if ((ielen == SST_AND_MAPPEDHPLMNSST_LENGTH)
|| (ielen == SST_AND_SD_AND_MAPPEDHPLMNSST_LENGTH)
|| (ielen == SST_AND_SD_AND_MAPPEDHPLMNSST_AND_MAPPEDHPLMNSD_LENGTH)) {
DECODE_U8(buffer + decoded, bitStream, decoded);
snssai->mappedhplmnsst = bitStream;
}
if (ielen == SST_AND_SD_AND_MAPPEDHPLMNSST_AND_MAPPEDHPLMNSD_LENGTH) {
DECODE_U8(buffer + decoded, bitStream, decoded);
bit32Stream = (uint32_t) (bitStream & 0Xff);
DECODE_U8(buffer + decoded, bitStream, decoded);
bit32Stream |= (uint32_t) ((bitStream << 8) & 0xff00);
DECODE_U8(buffer + decoded, bitStream, decoded);
bit32Stream |= (uint32_t) ((bitStream << 16) & 0xff0000);
snssai->mappedhplmnsd = bit32Stream;
}
return decoded;
}
......@@ -10,24 +10,23 @@
#define SNSSAI_MINIMUM_LENGTH_TLV 3
#define SNSSAI_MAXIMUM_LENGTH_TLV 10
typedef enum{
SST_LENGHT = 0b00000001,
SST_AND_MAPPEDHPLMNSST_LENGHT = 0b00000010,
SST_AND_SD_LENGHT = 0b00000100,
SST_AND_SD_AND_MAPPEDHPLMNSST_LENGHT = 0b00000101,
SST_AND_SD_AND_MAPPEDHPLMNSST_AND_MAPPEDHPLMNSD_LENGHT = 0b00001000
}length_of_snssai_contents;
typedef struct{
length_of_snssai_contents len;
uint8_t sst;
uint32_t sd:24;
uint8_t mappedhplmnsst;
uint32_t mappedhplmnsd;
typedef enum {
SST_LENGTH = 0b00000001,
SST_AND_MAPPEDHPLMNSST_LENGTH = 0b00000010,
SST_AND_SD_LENGTH = 0b00000100,
SST_AND_SD_AND_MAPPEDHPLMNSST_LENGTH = 0b00000101,
SST_AND_SD_AND_MAPPEDHPLMNSST_AND_MAPPEDHPLMNSD_LENGTH = 0b00001000
} length_of_snssai_contents;
typedef struct {
length_of_snssai_contents len;
uint8_t sst;
uint32_t sd :24;
uint8_t mappedhplmnsst;
uint32_t mappedhplmnsd;
} SNSSAI;
int encode_snssai ( SNSSAI snssai, uint8_t iei, uint8_t * buffer, uint32_t len ) ;
int decode_snssai ( SNSSAI * snssai, uint8_t iei, uint8_t * buffer, uint32_t len ) ;
int encode_snssai(SNSSAI snssai, uint8_t iei, uint8_t *buffer, uint32_t len);
int decode_snssai(SNSSAI *snssai, uint8_t iei, uint8_t *buffer, uint32_t len);
#endif
......@@ -271,9 +271,6 @@ ADD_SUBDIRECTORY(${CMAKE_CURRENT_SOURCE_DIR}/../../src/gtpv2c ${CMAKE_CURRENT_BI
ADD_SUBDIRECTORY(${CMAKE_CURRENT_SOURCE_DIR}/../../src/pfcp ${CMAKE_CURRENT_BINARY_DIR}/pfcp)
ADD_SUBDIRECTORY(${CMAKE_CURRENT_SOURCE_DIR}/../../src/udp ${CMAKE_CURRENT_BINARY_DIR}/udp)
ADD_SUBDIRECTORY(${CMAKE_CURRENT_SOURCE_DIR}/../../src/api-server ${CMAKE_CURRENT_BINARY_DIR}/api-server)
if(${SGW_AUTOTEST})
ADD_SUBDIRECTORY(${CMAKE_CURRENT_SOURCE_DIR}/../../src/gtpv1u ${CMAKE_CURRENT_BINARY_DIR}/gtpv1u)
endif(${SGW_AUTOTEST})
#ENABLE_TESTING()
#ADD_SUBDIRECTORY(${CMAKE_CURRENT_SOURCE_DIR}/../../src/test ${CMAKE_CURRENT_BINARY_DIR}/test)
......@@ -381,9 +378,6 @@ IF(STATIC_LINKING)
SET(ASAN)
ENDIF(STATIC_LINKING)
if(${SGW_AUTOTEST})
SET(GTPV1U_LIB GTPV1U)
endif(${SGW_AUTOTEST})
target_link_libraries (smf ${ASAN} -Wl,--start-group CN_UTILS SMF UDP ${GTPV1U_LIB} GTPV2C PFCP 3GPP_COMMON_TYPES SMF_API -lnettle ${NETTLE_LIBRARIES} ${CRYPTO_LIBRARIES} NAS gflags glog dl double-conversion folly -Wl,--end-group pthread m rt config++ event boost_system pistache curl)
target_link_libraries (smf ${ASAN} -Wl,--start-group CN_UTILS SMF UDP GTPV2C PFCP 3GPP_COMMON_TYPES SMF_API -lnettle ${NETTLE_LIBRARIES} ${CRYPTO_LIBRARIES} NAS gflags glog dl double-conversion folly -Wl,--end-group pthread m rt config++ event boost_system pistache curl)
......@@ -516,7 +516,9 @@ void smf_app::handle_pdu_session_create_sm_context_request(
"NAS, pdu_session_type %d",
decoded_nas_msg.plain.sm.pdu_session_establishment_request
._pdusessiontype.pdu_session_type_value);
smreq->req.set_pdu_session_type(decoded_nas_msg.plain.sm.pdu_session_establishment_request._pdusessiontype.pdu_session_type_value);
smreq->req.set_pdu_session_type(
decoded_nas_msg.plain.sm.pdu_session_establishment_request
._pdusessiontype.pdu_session_type_value);
}
//Get necessary information
......@@ -564,6 +566,8 @@ void smf_app::handle_pdu_session_create_sm_context_request(
Pistache::Http::Code::Forbidden, n1_sm_message_hex);
}
context_req_msg.set_pti(pti);
//check pdu session id
if ((pdu_session_id == PDU_SESSION_IDENTITY_UNASSIGNED )
|| (pdu_session_id > PDU_SESSION_IDENTITY_LAST )) {
......
......@@ -56,10 +56,15 @@ namespace smf {
#define TASK_SMF_APP_TRIGGER_T3591 (0)
#define TASK_SMF_APP_TIMEOUT_T3591 (1)
#define TASK_SMF_APP_TRIGGER_T3592 (2)
#define TASK_SMF_APP_TIMEOUT_T3592 (3)
//Table 10.3.2 @3GPP TS 24.501 V16.1.0 (2019-06)
#define T3591_TIMER_VALUE_SEC 16
#define T3591_TIMER_MAX_RETRIES 4
#define T3592_TIMER_VALUE_SEC 16
#define T3592_TIMER_MAX_RETRIES 4
typedef enum {
PDU_SESSION_ESTABLISHMENT = 1,
......
This diff is collapsed.
......@@ -131,11 +131,13 @@ class smf_pdu_session : public std::enable_shared_from_this<smf_pdu_session> {
pdu_session_status = pdu_session_status_e::PDU_SESSION_INACTIVE;
timer_T3590 = ITTI_INVALID_TIMER_ID;
timer_T3591 = ITTI_INVALID_TIMER_ID;
timer_T3592 = ITTI_INVALID_TIMER_ID;
}
smf_pdu_session(smf_pdu_session &b) = delete;
void set(const paa_t &paa);
void get_paa(paa_t &paa);
bool get_qos_flow(const pfcp::pdr_id_t &pdr_id, smf_qos_flow &q);
bool get_qos_flow(const pfcp::far_id_t &far_id, smf_qos_flow &q);
......@@ -184,6 +186,7 @@ class smf_pdu_session : public std::enable_shared_from_this<smf_pdu_session> {
void generate_qos_rule_id(uint8_t &rule_id);
void release_qos_rule_id(const uint8_t &rule_id);
pdn_type_t get_pdn_type() const;
bool ipv4; // IP Address(es): IPv4 address and/or IPv6 prefix
bool ipv6; // IP Address(es): IPv4 address and/or IPv6 prefix
......@@ -212,6 +215,7 @@ class smf_pdu_session : public std::enable_shared_from_this<smf_pdu_session> {
pdu_session_status_e pdu_session_status;
timer_id_t timer_T3590;
timer_id_t timer_T3591;
timer_id_t timer_T3592;
//N3 tunnel status (ACTIVATED, DEACTIVATED, ACTIVATING)
upCnx_state_e upCnx_state;
//5GSM parameters and capabilities
......@@ -272,6 +276,8 @@ class dnn_context {
/* Insert a PDU Session into the DNN context */
void insert_pdu_session(std::shared_ptr<smf_pdu_session> &sp);
/* get number of pdu sessions associated with this context (dnn and Nssai) */
size_t get_number_pdu_sessions();
std::string toString() const;
......
......@@ -146,25 +146,26 @@ void pdu_session_msg::set_pdu_session_type(uint8_t const &pdu_session_type) {
}
//-----------------------------------------------------------------------------
extended_protocol_discriminator_t pdu_session_create_sm_context::get_epd() const {
return m_epd;
procedure_transaction_id_t pdu_session_msg::get_pti() const {
return m_pti;
}
//-----------------------------------------------------------------------------
void pdu_session_create_sm_context::set_epd(
extended_protocol_discriminator_t const &epd) {
m_epd = epd;
void pdu_session_msg::set_pti(
procedure_transaction_id_t const &pti) {
m_pti = pti;
}
//-----------------------------------------------------------------------------
procedure_transaction_id_t pdu_session_create_sm_context::get_pti() const {
return m_pti;
extended_protocol_discriminator_t pdu_session_create_sm_context::get_epd() const {
return m_epd;
}
//-----------------------------------------------------------------------------
void pdu_session_create_sm_context::set_pti(
procedure_transaction_id_t const &pti) {
m_pti = pti;
void pdu_session_create_sm_context::set_epd(
extended_protocol_discriminator_t const &epd) {
m_epd = epd;
}
//-----------------------------------------------------------------------------
......@@ -370,6 +371,12 @@ void pdu_session_update_sm_context_request::add_qfi(pfcp::qfi_t const &qfi) {
qfis.push_back(qfi);
}
//-----------------------------------------------------------------------------
void pdu_session_update_sm_context_request::add_qfi(uint8_t const &q) {
pfcp::qfi_t qfi(q);
qfis.push_back(qfi);
}
//-----------------------------------------------------------------------------
void pdu_session_update_sm_context_request::get_qfis(
std::vector<pfcp::qfi_t> &q) {
......@@ -412,17 +419,6 @@ void pdu_session_update_sm_context_request::set_an_type(
m_an_type = value;
}
//-----------------------------------------------------------------------------
procedure_transaction_id_t pdu_session_update_sm_context_response::get_pti() const {
return m_pti;
}
//-----------------------------------------------------------------------------
void pdu_session_update_sm_context_response::set_pti(
procedure_transaction_id_t const &pti) {
m_pti = pti;
}
//-----------------------------------------------------------------------------
void pdu_session_update_sm_context_response::set_cause(uint8_t cause) {
m_cause = cause;
......
......@@ -133,6 +133,9 @@ class pdu_session_msg {
uint8_t get_pdu_session_type() const;
void set_pdu_session_type(uint8_t const &pdu_session_type);
procedure_transaction_id_t get_pti() const;
void set_pti(procedure_transaction_id_t const &pti);
private:
pdu_session_msg_type_t m_msg_type;
std::string m_api_root;
......@@ -142,6 +145,7 @@ class pdu_session_msg {
std::string m_dnn;
snssai_t m_snssai;
uint8_t m_pdu_session_type;
procedure_transaction_id_t m_pti;
};
//---------------------------------------------------------------------------------------
......@@ -174,15 +178,11 @@ class pdu_session_create_sm_context : public pdu_session_msg {
extended_protocol_discriminator_t get_epd() const;
void set_epd(extended_protocol_discriminator_t const &epd);
procedure_transaction_id_t get_pti() const;
void set_pti(procedure_transaction_id_t const &pti);
uint8_t get_message_type() const;
void set_message_type(uint8_t const &message_type);
private:
extended_protocol_discriminator_t m_epd;
procedure_transaction_id_t m_pti;
uint8_t m_message_type;
};
......@@ -420,6 +420,7 @@ class pdu_session_update_sm_context_request : public pdu_session_msg {
bool n1_sm_msg_is_set() const;
bool n2_sm_info_is_set() const;
void add_qfi(pfcp::qfi_t const &qfi);
void add_qfi(uint8_t const &qfi);
void get_qfis(std::vector<pfcp::qfi_t> &q);
void set_dl_fteid(fteid_t const &t);
void get_dl_fteid(fteid_t &t);
......@@ -487,7 +488,6 @@ class pdu_session_update_sm_context_response : public pdu_session_msg {
pdu_session_update_sm_context_response()
:
pdu_session_msg(PDU_SESSION_UPDATE_SM_CONTEXT_RESPONSE) {
m_pti = { };
m_cause = 0;
m_n1_sm_msg_is_set = false;
m_n2_sm_info_is_set = false;
......@@ -514,11 +514,8 @@ class pdu_session_update_sm_context_response : public pdu_session_msg {
std::map<uint8_t, qos_flow_context_updated> &all_flows);
void remove_all_qos_flow_context_updateds();
nlohmann::json sm_context_updated_data; //N1N2MessageTransferReqData from oai::amf::model
procedure_transaction_id_t get_pti() const;
void set_pti(procedure_transaction_id_t const &pti);
private:
procedure_transaction_id_t m_pti;
uint8_t m_cause;
std::string m_n1_sm_message; //N1 SM after decoding
bool m_n1_sm_msg_is_set;
......
......@@ -341,7 +341,7 @@ void smf_n11::send_pdu_session_update_sm_context_response(
break;
case session_management_procedures_type_e::PDU_SESSION_ESTABLISHMENT_UE_REQUESTED: {
Logger::smf_n11().debug("PDU_SESSION_ESTABLISHMENT_UE_REQUESTED");
Logger::smf_n11().info("PDU_SESSION_ESTABLISHMENT_UE_REQUESTED");
std::string json_part =
sm_context_res->res.sm_context_updated_data.dump();
sm_context_res->http_response.headers()
......@@ -353,7 +353,7 @@ void smf_n11::send_pdu_session_update_sm_context_response(
break;
case session_management_procedures_type_e::PDU_SESSION_MODIFICATION_UE_INITIATED_STEP1: {
Logger::smf_n11().debug("PDU_SESSION_MODIFICATION_UE_INITIATED");
Logger::smf_n11().info("PDU_SESSION_MODIFICATION_UE_INITIATED");
std::string boundary = "----Boundary";
std::string json_part =
......@@ -406,6 +406,26 @@ void smf_n11::send_pdu_session_update_sm_context_response(
}
break;
case session_management_procedures_type_e::PDU_SESSION_RELEASE_UE_REQUESTED_STEP1: {
Logger::smf_n11().debug("PDU_SESSION_RELEASE_UE_REQUESTED_STEP1");
std::string boundary = "----Boundary";
std::string json_part =
sm_context_res->res.sm_context_updated_data.dump();
std::string n1_message = sm_context_res->res.get_n1_sm_message();
std::string n2_message = sm_context_res->res.get_n2_sm_information();
std::string body;
create_multipart_related_content(body, json_part, boundary, n1_message,
n2_message);
sm_context_res->http_response.headers()
.add<Pistache::Http::Header::ContentType>(
Pistache::Http::Mime::MediaType(
"multipart/related; boundary=" + boundary));
sm_context_res->http_response.send(Pistache::Http::Code::Ok, body);
}
break;
default: {
Logger::smf_n11().debug("Session management procedure: unknown!");
}
......
This diff is collapsed.
This diff is collapsed.
......@@ -171,6 +171,43 @@ class session_update_sm_context_procedure : public smf_procedure {
};
//------------------------------------------------------------------------------
class session_release_pdu_session_procedure : public smf_procedure {
public:
explicit session_release_pdu_session_procedure(
std::shared_ptr<smf_pdu_session> &sppc)
:
smf_procedure(),
ppc(sppc),
n4_triggered(),
n11_triggered_pending(),
n11_trigger(),
session_procedure_type() {
}
int run(std::shared_ptr<itti_n11_update_sm_context_request> req,
std::shared_ptr<itti_n11_update_sm_context_response> resp,
std::shared_ptr<smf::smf_context> sc);
/*
* Handle N4 modification response from UPF
* @param [itti_n4_session_modification_response] resp
* @param [std::shared_ptr<smf::smf_context>] sc smf context
* @return void
*/
void handle_itti_msg(itti_n4_session_modification_response &resp,
std::shared_ptr<smf::smf_context> sc);
std::shared_ptr<itti_n4_session_modification_request> n4_triggered;
std::shared_ptr<smf_pdu_session> ppc;
std::shared_ptr<smf::smf_context> pc;
std::shared_ptr<itti_n11_update_sm_context_request> n11_trigger;
std::shared_ptr<itti_n11_update_sm_context_response> n11_triggered_pending;
session_management_procedures_type_e session_procedure_type;
};
}
#include "../smf_app/smf_context.hpp"
......
This diff is collapsed.
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