Commit 878e3e11 authored by Tien-Thinh Nguyen's avatar Tien-Thinh Nguyen
Browse files

PDU session modification (UE-requested, step1)

parent 31e0877d
......@@ -48,7 +48,8 @@ typedef uint8_t pdu_session_id_t;
/* QFI */
// type: integer, minimum: 0, maximum: 63
#define QOS_FLOW_IDENTIFIER_FIRST (uint8_t)0
#define NO_QOS_FLOW_IDENTIFIER_ASSIGNED (uint8_t)0
#define QOS_FLOW_IDENTIFIER_FIRST (uint8_t)1
#define QOS_FLOW_IDENTIFIER_LAST (uint8_t)63
/*
......@@ -64,6 +65,12 @@ typedef uint8_t pdu_session_id_t;
} smf_qfi_t;
*/
//QoS Rule
#define NO_QOS_RULE_IDENTIFIER_ASSIGNED (uint8_t)0
#define QOS_RULE_IDENTIFIER_FIRST (uint8_t)1
#define QOS_RULE_IDENTIFIER_LAST (uint8_t)255
// Integrity protection maximum data rate
typedef struct ipmdr_s {
uint8_t ul;
......
......@@ -166,10 +166,10 @@ typedef struct qos_profile_s {
arp_5gc_t arp;
uint8_t priority_level;
qos_profile_type_e profile_type;
union parameter {
union {
reflective_qos_attribute_e rqa; //Reflective QoS Attribute (RQA)
qos_profile_gbr_t qos_profile_gbr; //Attributes for GBR
};
} parameter;
} qos_profile_t;
enum class multipart_related_content_part_e {
......
......@@ -109,7 +109,7 @@ extern "C" {
#define PDU_SESSION_MODIFICATION_REJECT 0b11001010
#define PDU_SESSION_MODIFICATION_COMMAND 0b11001011
#define PDU_SESSION_MODIFICATION_COMPLETE 0b11001100
#define PDU_SESSION_MODIFICATION_COMMANDREJECT 0b11001101
#define PDU_SESSION_MODIFICATION_COMMAND_REJECT 0b11001101
#define PDU_SESSION_RELEASE_REQUEST 0b11010001
#define PDU_SESSION_RELEASE_REJECT 0b11010010
......@@ -118,6 +118,7 @@ extern "C" {
#define _5GSM_STATUS 0b11010110
// 9.11.3.47 Request type
//typedef std::string request_type_t;
......@@ -332,7 +333,6 @@ typedef struct pdu_session_type_s {
} pdu_session_type_t;
#endif
#endif
......@@ -106,7 +106,7 @@ int sm_msg_decode(SM_msg *msg, uint8_t *buffer, uint32_t len) {
decode_result = decode_pdu_session_modification_complete(
&msg->pdu_session_modification_complete, buffer, len);
break;
case PDU_SESSION_MODIFICATION_COMMANDREJECT:
case PDU_SESSION_MODIFICATION_COMMAND_REJECT:
decode_result = decode_pdu_session_modification_command_reject(
&msg->pdu_session_modification_command_reject, buffer, len);
break;
......@@ -218,7 +218,7 @@ int fivegsm_msg_encode(SM_msg *msg, uint8_t *buffer, uint32_t len) {
encode_result = encode_pdu_session_modification_complete(
&msg->pdu_session_modification_complete, buffer, len);
break;
case PDU_SESSION_MODIFICATION_COMMANDREJECT:
case PDU_SESSION_MODIFICATION_COMMAND_REJECT:
encode_result = encode_pdu_session_modification_command_reject(
&msg->pdu_session_modification_command_reject, buffer, len);
break;
......
This diff is collapsed.
......@@ -78,6 +78,9 @@ class smf_qos_flow {
far_id_ul = { };
far_id_dl = { };
released = false;
qos_rules_to_be_synchronised = {};
qos_rules = {};
qos_profile = {};
}
void deallocate_ressources();
......@@ -100,10 +103,16 @@ class smf_qos_flow {
std::pair<bool, pfcp::far_id_t> far_id_dl;
bool released; // finally seems necessary, TODO try to find heuristic ?
void get_default_qos_rule(QOSRulesIE &qos_rule) const;
void get_qos_rule(uint8_t rule_id, QOSRulesIE &qos_rule) const;
void update_qos_rule(QOSRulesIE qos_rule);
void add_qos_rule(QOSRulesIE qos_rule);
pdu_session_id_t pdu_session_id;
//qos_rules[0]: default rule
std::vector<QOSRulesIE> qos_rules;
//rule_id <-> qos_rule
std::map<uint8_t, QOSRulesIE> qos_rules;
//std::vector<QOSRulesIE> qos_rules;
std::vector<uint8_t> qos_rules_to_be_synchronised;
//QoS profile
qos_profile_t qos_profile;
//cause
......@@ -188,6 +197,9 @@ class smf_pdu_session : public std::enable_shared_from_this<smf_pdu_session> {
void release_qos_rule_id(const uint8_t &rule_id);
pdn_type_t get_pdn_type() const;
void get_qos_rules_to_be_synchronised(std::vector<QOSRulesIE> &qos_rules) const;
bool ipv4; // IP Address(es): IPv4 address and/or IPv6 prefix
bool ipv6; // IP Address(es): IPv4 address and/or IPv6 prefix
struct in_addr ipv4_address; // IP Address(es): IPv4 address and/or IPv6 prefix
......@@ -272,7 +284,10 @@ class dnn_context {
/* Find the PDU Session */
bool find_pdu_session(const uint32_t pdu_session_id,
std::shared_ptr<smf_pdu_session> &pdn);
std::shared_ptr<smf_pdu_session> &pdu_session);
//void create_or_update_qos_rule(QOSRulesIE &qos_rule, pfcp::qfi_t qfi,
// pdu_session_id_t pdu_id);
/* Insert a PDU Session into the DNN context */
void insert_pdu_session(std::shared_ptr<smf_pdu_session> &sp);
......
......@@ -536,6 +536,25 @@ void smf_n11::send_pdu_session_create_sm_context_response(
}
//------------------------------------------------------------------------------
void smf_n11::send_pdu_session_update_sm_context_response(
Pistache::Http::ResponseWriter &httpResponse,
oai::smf_server::model::SmContextUpdatedData &smContextUpdatedData,
Pistache::Http::Code code) {
Logger::smf_n11().debug(
"[SMF N11] Send PDUSessionUpdateContextResponse to AMF!");
nlohmann::json json_data = { };
to_json(json_data, smContextUpdatedData);
if (!json_data.empty()) {
httpResponse.headers().add<Pistache::Http::Header::ContentType>(
Pistache::Http::Mime::MediaType("application/json"));
httpResponse.send(code, json_data.dump().c_str());
} else {
httpResponse.send(code);
}
}
//------------------------------------------------------------------------------
void smf_n11::send_pdu_session_create_sm_context_response(
Pistache::Http::ResponseWriter &httpResponse,
......
......@@ -36,6 +36,7 @@
#include "3gpp_29.503.h"
#include "smf_context.hpp"
#include "SmContextCreatedData.h"
#include "SmContextUpdatedData.h"
#include "SmContextUpdateError.h"
namespace smf {
......@@ -89,6 +90,18 @@ class smf_n11 {
oai::smf_server::model::SmContextUpdateError &smContextUpdateError,
Pistache::Http::Code code);
/*
* Send Update session response to AMF
* @param [Pistache::Http::ResponseWriter] httpResponse
* @param [ oai::smf_server::model::SmContextUpdatedData] smContextUpdatedData
* @param [Pistache::Http::Code] code, response code
*
*/
void send_pdu_session_update_sm_context_response(
Pistache::Http::ResponseWriter &httpResponse,
oai::smf_server::model::SmContextUpdatedData &smContextUpdatedData,
Pistache::Http::Code code);
/*
* Send create session response to AMF
* @param [Pistache::Http::ResponseWriter] httpResponse
......
......@@ -112,6 +112,7 @@ void smf_n1_n2::create_n1_sm_container(pdu_session_msg &msg,
//PDU Session Identity
sm_msg->header.pdu_session_identity = msg.get_pdu_session_id();
switch (n1_msg_type) {
//PDU Session Establishment Accept
......@@ -469,98 +470,75 @@ void smf_n1_n2::create_n1_sm_container(pdu_session_msg &msg,
Logger::smf_app().info(
"PDU_SESSION_MODIFICATION_COMMAND, encode starting...");
//Fill the content of PDU Session Establishment Request message with hardcoded values (to be completed)
//PTI
sm_msg->header.procedure_transaction_identity = sm_context_res.get_pti()
.procedure_transaction_id;
//Message Type
sm_msg->header.message_type = PDU_SESSION_MODIFICATION_COMMAND;
//PDU Session Type
sm_msg->pdu_session_modification_command.messagetype = sm_context_res
.get_msg_type();
//Presence
sm_msg->pdu_session_modification_command.presence = 0xff; //TODO: to be updated
//5GSMCause
sm_msg->pdu_session_modification_command._5gsmcause =
static_cast<uint8_t>(sm_cause); //sm_context_res.get_cause();
/*
ExtendedProtocolDiscriminator extendedprotocoldiscriminator;
PDUSessionIdentity pdusessionidentity;
ProcedureTransactionIdentity proceduretransactionidentity;
MessageType messagetype;
uint8_t presence;
_5GSMCause _5gsmcause;
SessionAMBR sessionambr;
GPRSTimer gprstimer;
AlwaysonPDUSessionIndication alwaysonpdusessionindication;
QOSRules qosrules;
MappedEPSBearerContexts mappedepsbearercontexts;
QOSFlowDescriptions qosflowdescriptions;
ExtendedProtocolConfigurationOptions extendedprotocolconfigurationoptions;
*/
//SessionAMBR
//TODO: get from subscription DB
//Get the SMF_PDU_Session
std::shared_ptr<smf_context> sc = { };
std::shared_ptr<dnn_context> sd = { };
std::shared_ptr<smf_pdu_session> sp = { };
supi_t supi = sm_context_res.get_supi();
supi64_t supi64 = smf_supi_to_u64(supi);
std::shared_ptr<smf_context> sc = { };
if (smf_app_inst->is_supi_2_smf_context(supi64)) {
Logger::smf_app().debug("Get SMF context with SUPI " SUPI_64_FMT "",
supi64);
sc = smf_app_inst->supi_2_smf_context(supi64);
sc.get()->get_session_ambr(
sm_msg->pdu_session_modification_command.sessionambr,
sm_context_res.get_snssai(), sm_context_res.get_dnn());
} else {
Logger::smf_app().warn(
"SMF context with SUPI " SUPI_64_FMT " does not exist!", supi64);
//TODO:
}
//GPRSTimer
//TODO:
//AlwaysonPDUSessionIndication
//TODO:
bool find_dnn = sc.get()->find_dnn_context(sm_context_res.get_snssai(),
sm_context_res.get_dnn(), sd);
bool find_pdu = false;
if (find_dnn) {
find_pdu = sd.get()->find_pdu_session(
sm_context_res.get_pdu_session_id(), sp);
}
if (!find_dnn or !find_pdu) {
//error
Logger::smf_app().warn("DNN or PDU session context does not exist!");
//TODO:
return;
}
//Fill the content of PDU Session Establishment Request message with hardcoded values (to be completed)
//PTI
sm_msg->header.procedure_transaction_identity = sm_context_res.get_pti()
.procedure_transaction_id;
//Message Type
sm_msg->header.message_type = PDU_SESSION_MODIFICATION_COMMAND;
//Presence
sm_msg->pdu_session_modification_command.presence = 0xff; //TODO: to be updated
//5GSMCause
sm_msg->pdu_session_modification_command._5gsmcause =
static_cast<uint8_t>(sm_cause);
//SessionAMBR (default)
sc.get()->get_session_ambr(
sm_msg->pdu_session_modification_command.sessionambr,
sm_context_res.get_snssai(), sm_context_res.get_dnn());
//TODO: GPRSTimer
//TODO: AlwaysonPDUSessionIndication
//QOSRules
sm_msg->pdu_session_modification_command.qosrules.lengthofqosrulesie = 1;
//Get the authorized QoS Rules
std::vector<QOSRulesIE> qos_rules;
sp.get()->get_qos_rules_to_be_synchronised(qos_rules);
sm_msg->pdu_session_modification_command.qosrules.lengthofqosrulesie =
qos_rules.size();
sm_msg->pdu_session_modification_command.qosrules.qosrulesie =
(QOSRulesIE*) calloc(1, sizeof(QOSRulesIE));
sm_msg->pdu_session_modification_command.qosrules.qosrulesie[0]
.qosruleidentifer = 0x01;
sm_msg->pdu_session_modification_command.qosrules.qosrulesie[0]
.ruleoperationcode = CREATE_NEW_QOS_RULE;
sm_msg->pdu_session_modification_command.qosrules.qosrulesie[0].dqrbit =
THE_QOS_RULE_IS_DEFAULT_QOS_RULE;
sm_msg->pdu_session_modification_command.qosrules.qosrulesie[0]
.numberofpacketfilters = 1;
//1st rule
sm_msg->pdu_session_modification_command.qosrules.qosrulesie[0]
.packetfilterlist.create_modifyandadd_modifyandreplace =
(Create_ModifyAndAdd_ModifyAndReplace*) calloc(
1, sizeof(Create_ModifyAndAdd_ModifyAndReplace));
sm_msg->pdu_session_modification_command.qosrules.qosrulesie[0]
.packetfilterlist.create_modifyandadd_modifyandreplace
->packetfilterdirection = 0b01;
sm_msg->pdu_session_modification_command.qosrules.qosrulesie[0]
.packetfilterlist.create_modifyandadd_modifyandreplace
->packetfilteridentifier = 1;
sm_msg->pdu_session_modification_command.qosrules.qosrulesie[0]
.packetfilterlist.create_modifyandadd_modifyandreplace
->packetfiltercontents.component_type = QOS_RULE_MATCHALL_TYPE;
sm_msg->pdu_session_modification_command.qosrules.qosrulesie[0]
.qosruleprecedence = 1;
sm_msg->pdu_session_modification_command.qosrules.qosrulesie[0]
.segregation = SEGREGATION_NOT_REQUESTED;
sm_msg->pdu_session_modification_command.qosrules.qosrulesie[0]
.qosflowidentifer = 60;
for (int i = 0; i < qos_rules.size(); i++) {
sm_msg->pdu_session_modification_command.qosrules.qosrulesie[i] =
qos_rules[i];
}
//MappedEPSBearerContexts
//TODO:
//QOSFlowDescriptions
//authorized QoS flow descriptions IE: QoSFlowDescritions
//QOSFlowDescriptions, TODO: get authorized QoS flow descriptions IE
if (smf_app_inst->is_supi_2_smf_context(supi64)) {
Logger::smf_app().debug("Get SMF context with SUPI " SUPI_64_FMT "",
supi64);
......
......@@ -270,9 +270,11 @@ int session_create_sm_context_procedure::run(
QOSRulesIE qos_rule = { };
pc.get()->get_default_qos_rule(qos_rule,
sm_context_req->req.get_pdu_session_type());
q.qos_rules.push_back(qos_rule);
ppc->generate_qos_rule_id(q.qos_rules[0].qosruleidentifer);
q.qos_rules[0].qosflowidentifer = q.qfi.qfi;
uint8_t rule_id = {0};
ppc->generate_qos_rule_id(rule_id);
qos_rule.qosruleidentifer = rule_id;
qos_rule.qosflowidentifer = q.qfi.qfi;
q.add_qos_rule(qos_rule);
smf_qos_flow q2 = q;
ppc->add_qos_flow(q2);
......@@ -344,6 +346,7 @@ void session_create_sm_context_procedure::handle_itti_msg(
//TODO: how about pdu_session_id??
smf_qos_flow q = { };
QOSRulesIE qos_rule = {};
qos_flow_context_updated qos_flow = { }; //default flow, so Non-GBR, TODO: //we can use smf_qos_flow instead!
qos_flow.set_cause(REQUEST_ACCEPTED);
if (not ppc->get_qos_flow(qfi, q)) {
......@@ -354,7 +357,8 @@ void session_create_sm_context_procedure::handle_itti_msg(
} else {
qos_flow.set_ul_fteid(q.ul_fteid); //tunnel info
}
qos_flow.set_qos_rule(q.qos_rules[0]); //set default QoS rule
q.get_default_qos_rule(qos_rule);
qos_flow.set_qos_rule(qos_rule); //set default QoS rule
}
qos_flow.set_qfi(qfi);
qos_profile_t profile = { };
......@@ -1321,7 +1325,7 @@ void session_update_sm_context_procedure::handle_itti_msg(
//send ITTI message to N11 interface to trigger SessionUpdateSMContextResponse towards AMFs
Logger::smf_app().info("Sending ITTI message %s to task TASK_SMF_N11",
n11_triggered_pending->get_msg_name());
n11_triggered_pending->session_procedure_type = session_procedure_type; //session_management_procedures_type_e::PDU_SESSION_ESTABLISHMENT_UE_REQUESTED;
n11_triggered_pending->session_procedure_type = session_procedure_type;
int ret = itti_inst->send_msg(n11_triggered_pending);
if (RETURNok != ret) {
Logger::smf_app().error(
......
......@@ -879,16 +879,16 @@ int main(int argc, char *argv[]) {
usleep(100000);
send_pdu_session_update_sm_context_establishment(smf_ip_address);
usleep(200000);
//UE-initiated Service Request
send_pdu_session_update_sm_context_ue_service_request(smf_ip_address);
usleep(200000);
send_pdu_session_update_sm_context_ue_service_request_step2(smf_ip_address);
//PDU Session Release procedure
/* send_pdu_session_release_request(smf_ip_address);
send_pdu_session_release_request(smf_ip_address);
usleep(200000);
send_pdu_session_release_resource_release_ack(smf_ip_address);
usleep(200000);
send_pdu_session_release_complete(smf_ip_address);
*/
send_pdu_session_update_sm_context_ue_service_request(smf_ip_address);
usleep(200000);
send_pdu_session_update_sm_context_ue_service_request_step2(smf_ip_address);
return 0;
}
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