Skip to content
GitLab
Menu
Projects
Groups
Snippets
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
Menu
Open sidebar
oai
cn5g
oai-cn5g-smf
Commits
85eb18a3
Commit
85eb18a3
authored
Sep 24, 2019
by
Tien-Thinh Nguyen
Browse files
support PDUSession_CreateSMContextRequest
parent
8bd91b97
Changes
15
Hide whitespace changes
Inline
Side-by-side
src/common/3gpp_29.502.h
0 → 100644
View file @
85eb18a3
/*
* 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 Apache License, Version 2.0 (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.apache.org/licenses/LICENSE-2.0
*
* 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 FILE_3GPP_29_502_SMF_SEEN
#define FILE_3GPP_29_502_SMF_SEEN
enum
pdu_session_application_error_e
{
PDU_SESSION_APPLICATION_ERROR_N1_SM_ERROR
=
1
,
PDU_SESSION_APPLICATION_ERROR_SNSSAI_DENIED
=
2
,
PDU_SESSION_APPLICATION_ERROR_DNN_DENIED
=
3
,
PDU_SESSION_APPLICATION_ERROR_PDUTYPE_DENIED
=
4
,
PDU_SESSION_APPLICATION_ERROR_SSC_DENIED
=
5
,
PDU_SESSION_APPLICATION_ERROR_SUBSCRIPTION_DENIED
=
6
,
PDU_SESSION_APPLICATION_ERROR_DNN_NOT_SUPPORTED
=
7
,
PDU_SESSION_APPLICATION_ERROR_PDUTYPE_NOT_SUPPORTED
=
8
,
PDU_SESSION_APPLICATION_ERROR_SSC_NOT_SUPPORTED
=
9
,
PDU_SESSION_APPLICATION_ERROR_HOME_ROUTED_ROAMING_REQUIRED
=
10
,
PDU_SESSION_APPLICATION_ERROR_OUT_OF_LADN_SERVICE_AREA
=
11
,
PDU_SESSION_APPLICATION_ERROR_N2_SM_ERROR
=
12
,
PDU_SESSION_APPLICATION_ERROR_PRIORITIZED_SERVICES_ONLY
=
13
,
PDU_SESSION_APPLICATION_ERROR_PDU_SESSION_ANCHOR_CHANGE
=
14
,
PDU_SESSION_APPLICATION_ERROR_TARGET_MME_CAPABILITY
=
15
,
PDU_SESSION_APPLICATION_ERROR_NO_EPS_5GS_CONTINUITY
=
16
,
PDU_SESSION_APPLICATION_ERROR_UNABLE_TO_PAGE_UE
=
17
,
PDU_SESSION_APPLICATION_ERROR_UE_NOT_RESPONDING
=
18
,
PDU_SESSION_APPLICATION_ERROR_REJECTED_BY_UE
=
19
,
PDU_SESSION_APPLICATION_ERROR_REJECTED_DUE_VPLMN_POLICY
=
20
,
PDU_SESSION_APPLICATION_ERROR_HO_TAU_IN_PROGRESS
=
21
,
PDU_SESSION_APPLICATION_ERROR_INTEGRITY_PROTECTED_MDR_NOT_ACCEPTABLE
=
22
,
PDU_SESSION_APPLICATION_ERROR_EBI_EXHAUSTED
=
23
,
PDU_SESSION_APPLICATION_ERROR_EBI_REJECTED_LOCAL_POLICY
=
24
,
PDU_SESSION_APPLICATION_ERROR_EBI_REJECTED_NO_N26
=
25
,
PDU_SESSION_APPLICATION_ERROR_DEFAULT_EPS_BEARER_INACTIVE
=
26
,
PDU_SESSION_APPLICATION_ERROR_HANDOVER_RESOURCE_ALLOCATION_FAILURE
=
27
,
PDU_SESSION_APPLICATION_ERROR_CONTEXT_NOT_FOUND
=
28
,
PDU_SESSION_APPLICATION_ERROR_INSUFFICIENT_RESOURCES_SLICE
=
29
,
PDU_SESSION_APPLICATION_ERROR_INSUFFICIENT_RESOURCES_SLICE_DNN
=
30
,
PDU_SESSION_APPLICATION_ERROR_DNN_CONGESTION
=
31
,
PDU_SESSION_APPLICATION_ERROR_S_NSSAI_CONGESTION
=
32
,
PDU_SESSION_APPLICATION_ERROR_PEER_NOT_RESPONDING
=
33
,
PDU_SESSION_APPLICATION_ERROR_NETWORK_FAILURE
=
34
};
static
const
std
::
vector
<
std
::
string
>
pdu_session_application_error_e2str
=
{
"UNKNOWN ERROR"
,
"N1_SM_ERROR"
,
"SNSSAI_DENIED"
,
"DNN_DENIED"
,
"PDUTYPE_DENIED"
,
"SSC_DENIED"
,
"SUBSCRIPTION_DENIED"
,
"DNN_NOT_SUPPORTED"
,
"PDUTYPE_NOT_SUPPORTED"
,
"SSC_NOT_SUPPORTED"
,
"HOME_ROUTED_ROAMING_REQUIRED"
,
"OUT_OF_LADN_SERVICE_AREA"
,
"N2_SM_ERROR"
,
"PRIORITIZED_SERVICES_ONLY"
,
"PDU_SESSION_ANCHOR_CHANGE"
,
"TARGET_MME_CAPABILITY"
,
"NO_EPS_5GS_CONTINUITY"
,
"UNABLE_TO_PAGE_UE"
,
"UE_NOT_RESPONDING"
,
"REJECTED_BY_UE"
,
"REJECTED_DUE_VPLMN_POLICY"
,
"HO_TAU_IN_PROGRESS"
,
"INTEGRITY_PROTECTED_MDR_NOT_ACCEPTABLE"
,
"EBI_EXHAUSTED"
,
"EBI_REJECTED_LOCAL_POLICY"
,
"EBI_REJECTED_NO_N26"
,
"DEFAULT_EPS_BEARER_INACTIVE"
,
"HANDOVER_RESOURCE_ALLOCATION_FAILURE"
,
"CONTEXT_NOT_FOUND"
,
"INSUFFICIENT_RESOURCES_SLICE"
,
"INSUFFICIENT_RESOURCES_SLICE_DNN"
,
"DNN_CONGESTION"
,
"S_NSSAI_CONGESTION"
,
"PEER_NOT_RESPONDING"
,
"NETWORK_FAILURE"
};
#endif
src/common/3gpp_29.503.h
0 → 100644
View file @
85eb18a3
/*
* 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 Apache License, Version 2.0 (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.apache.org/licenses/LICENSE-2.0
*
* 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 FILE_3GPP_29_503_SMF_SEEN
#define FILE_3GPP_29_503_SMF_SEEN
#include "smf.h"
enum
ssc_mode_e
{
SSC_MODE_1
=
1
,
SSC_MODE_2
=
2
,
SSC_MODE_3
=
3
,
};
static
const
std
::
vector
<
std
::
string
>
ssc_mode_e2str
=
{
"Error"
,
"SSC_MODE_1"
,
"SSC_MODE_2"
,
"SSC_MODE_3"
};
typedef
struct
ssc_mode_s
{
uint8_t
ssc_mode
;
ssc_mode_s
()
:
ssc_mode
(
SSC_MODE_1
)
{}
ssc_mode_s
(
ssc_mode_e
mode
)
:
ssc_mode
(
mode
)
{}
ssc_mode_s
(
const
struct
ssc_mode_s
&
p
)
:
ssc_mode
(
p
.
ssc_mode
)
{}
}
ssc_mode_t
;
typedef
struct
pdu_session_types_s
{
pdu_session_type_t
default_session_type
;
std
::
vector
<
pdu_session_type_t
>
allowed_session_types
;
}
pdu_session_types_t
;
typedef
struct
ssc_modes_s
{
ssc_mode_t
default_ssc_mode
;
std
::
vector
<
ssc_mode_t
>
allowed_ssc_modes
;
}
ssc_modes_t
;
typedef
struct
session_ambr_s
{
std
::
string
uplink
;
std
::
string
downlink
;
}
session_ambr_t
;
typedef
struct
dnn_configuration_s
{
pdu_session_types_t
pdu_session_types
;
ssc_modes_t
ssc_modes
;
session_ambr_t
session_ambr
;
}
dnn_configuration_t
;
#endif
src/pgwc/CMakeLists.txt
View file @
85eb18a3
...
...
@@ -39,6 +39,8 @@ add_library (PGWC STATIC
pgw_s5s8.cpp
pgwc_procedure.cpp
pgwc_sxab.cpp
smf_n10.cpp
smf_msg.cpp
#pgw_pcef_emulation.cpp
)
src/pgwc/pgw_app.cpp
View file @
85eb18a3
...
...
@@ -34,9 +34,19 @@
#include "pgw_paa_dynamic.hpp"
#include "pgw_s5s8.hpp"
#include "pgwc_sxab.hpp"
#include "smf_n10.hpp"
#include "string.hpp"
#include "SmContextCreateError.h"
#include "3gpp_29.502.h"
extern
"C"
{
#include "sm_msg.h"
#include "PDUSessionEstablishmentRequest.h"
}
#include <stdexcept>
#include <iostream>
#include <cstdlib>
using
namespace
pgwc
;
...
...
@@ -46,6 +56,7 @@ extern pgw_app *pgw_app_inst;
extern
pgw_config
pgw_cfg
;
pgw_s5s8
*
pgw_s5s8_inst
=
nullptr
;
pgwc_sxab
*
pgwc_sxab_inst
=
nullptr
;
smf_n10
*
smf_n10_inst
=
nullptr
;
extern
itti_mw
*
itti_inst
;
void
pgw_app_task
(
void
*
);
...
...
@@ -286,6 +297,7 @@ pgw_app::pgw_app (const std::string& config_file) : m_s5s8_cp_teid_generator(),
try
{
pgw_s5s8_inst
=
new
pgw_s5s8
();
pgwc_sxab_inst
=
new
pgwc_sxab
();
smf_n10_inst
=
new
smf_n10
();
}
catch
(
std
::
exception
&
e
)
{
Logger
::
pgwc_app
().
error
(
"Cannot create PGW_APP: %s"
,
e
.
what
()
);
throw
;
...
...
@@ -627,4 +639,144 @@ void pgw_app::handle_itti_msg (std::shared_ptr<itti_sxab_session_report_request>
}
}
//------------------------------------------------------------------------------
bool
pgw_app
::
is_supi_2_smf_context
(
const
supi64_t
&
supi
)
const
{
//TODO
//context doesn't exist
return
false
;
}
//------------------------------------------------------------------------------
std
::
shared_ptr
<
pgw_context
>
pgw_app
::
supi_2_smf_context
(
const
supi64_t
&
supi
)
const
{
std
::
shared_lock
lock
(
m_supi2smf_context
);
return
supi2pgw_context
.
at
(
supi
);
}
//------------------------------------------------------------------------------
void
pgw_app
::
set_supi_2_smf_context
(
const
supi64_t
&
supi
,
std
::
shared_ptr
<
pgw_context
>
sc
)
{
//TODO: from set_imsi64_2_pgw_context
}
//------------------------------------------------------------------------------
bool
pgw_app
::
is_use_local_configuration_subscription_data
(
const
std
::
string
&
dnn_selection_mode
)
{
//TODO: should be implemented
return
false
;
//get Session Management Subscription from UDM
}
//------------------------------------------------------------------------------
bool
pgw_app
::
is_supi_dnn_snssai_subscription_data
(
supi_t
&
supi
,
std
::
string
&
dnn
,
snssai_t
&
snssai
)
{
//TODO: should be implemented
return
false
;
//Session Management Subscription from UDM isn't available
}
//------------------------------------------------------------------------------
bool
pgw_app
::
is_create_sm_context_request_valid
()
{
//TODO: should be implemented
return
true
;
}
//------------------------------------------------------------------------------
void
pgw_app
::
send_create_session_response
(
Pistache
::
Http
::
ResponseWriter
&
httpResponse
,
oai
::
smf
::
model
::
SmContextCreateError
&
smContextCreateError
,
Pistache
::
Http
::
Code
code
)
{
//Send reply to AMF
nlohmann
::
json
jsonData
;
to_json
(
jsonData
,
smContextCreateError
);
std
::
string
resBody
=
jsonData
.
dump
();
//httpResponse.headers().add<Pistache::Http::Header::Location>(url);
httpResponse
.
send
(
code
,
resBody
);
}
//------------------------------------------------------------------------------
void
pgw_app
::
handle_amf_msg
(
std
::
shared_ptr
<
pdu_session_create_sm_context_request
>&
sm_context_req_msg
,
Pistache
::
Http
::
ResponseWriter
&
httpResponse
){
//handle PDU Session Create SM Context Request as specified in section 4.3.2 3GPP TS 23.502
Logger
::
pgwc_app
().
info
(
"Handle AMF message"
);
//Step 1. get necessary information
Logger
::
pgwc_app
().
debug
(
"Handle AMF message, supi "
SUPI_64_FMT
" "
,
sm_context_req_msg
->
get_supi
());
std
::
string
dnn
=
sm_context_req_msg
->
get_dnn
();
snssai_t
snssai
=
sm_context_req_msg
->
get_snssai
();
std
::
string
requestType
=
sm_context_req_msg
->
get_request_type
();
supi_t
supi
=
sm_context_req_msg
->
get_supi
();
supi64_t
supi64
=
smf_supi_to_u64
(
supi
);
oai
::
smf
::
model
::
ProblemDetails
problem_details
;
pdu_session_establishment_request_msg
pdu_session_establishment_request
=
sm_context_req_msg
->
get_nas_msg
()
;
pdu_session_type_t
pdu_session_type
=
{.
pdu_session_type
=
(
uint8_t
)
pdu_session_establishment_request
.
_pdusessiontype
};
Logger
::
pgwc_app
().
debug
(
"Handle AMF message, _pdusessiontype: %d"
,
pdu_session_type
.
pdu_session_type
);
//Step 2. check if the DNN requested is valid
if
(
not
pgw_cfg
.
is_dotted_dnn_handled
(
dnn
,
pdu_session_type
))
{
// Not a valid request...
Logger
::
pgwc_app
().
warn
(
"Received PDU_SESSION_CREATESMCONTEXT_REQUEST unknown requested APN %s, ignore message"
,
dnn
.
c_str
());
oai
::
smf
::
model
::
SmContextCreateError
smContextCreateError
;
problem_details
.
setCause
(
pdu_session_application_error_e2str
[
PDU_SESSION_APPLICATION_ERROR_DNN_DENIED
]);
//create a PDU Session Establishment Response by relying on NAS and assign to smContextCeateError.m_N1SmMsg
//Send response to AMF
send_create_session_response
(
httpResponse
,
smContextCreateError
,
Pistache
::
Http
::
Code
::
Forbidden
);
return
;
}
//Step 3. create a context for this supi if not existed, otherwise update
std
::
shared_ptr
<
pgw_context
>
sc
;
if
(
is_supi_2_smf_context
(
supi64
))
{
Logger
::
pgwc_app
().
debug
(
"Update PGW context
\n
"
);
sc
=
supi_2_smf_context
(
supi64
);
}
else
{
Logger
::
pgwc_app
().
debug
(
"Create a new PGW context
\n
"
);
sc
=
std
::
shared_ptr
<
pgw_context
>
(
new
pgw_context
());
set_supi_2_smf_context
(
supi64
,
sc
);
}
//update context with dnn information
std
::
shared_ptr
<
dnn_context
>
sd
;
if
(
!
sc
.
get
()
->
find_dnn_context
(
dnn
,
sd
))
{
if
(
nullptr
==
sd
.
get
()){
//create a new one and insert to the list
Logger
::
pgwc_app
().
debug
(
"Create a DNN context and add to the PGW context
\n
"
);
sd
=
std
::
shared_ptr
<
dnn_context
>
(
new
dnn_context
(
dnn
));
//sd.get()->in_use = true;
sc
.
get
()
->
insert_dnn
(
sd
);
}
}
// step 4. retrieve Session Management Subscription data from UDM if not available (step 4, section 4.3.2 3GPP TS 23.502)
std
::
string
dnn_selection_mode
=
sm_context_req_msg
->
get_dnn_selection_mode
();
if
(
not
is_use_local_configuration_subscription_data
(
dnn_selection_mode
)
&&
not
is_supi_dnn_snssai_subscription_data
(
supi
,
dnn
,
snssai
))
{
//uses a dummy UDM to test this part
Logger
::
pgwc_app
().
debug
(
"Retrieve Session Management Subscription data from UDM"
);
std
::
shared_ptr
<
session_management_subscription
>
subscription
=
std
::
shared_ptr
<
session_management_subscription
>
(
new
session_management_subscription
(
snssai
));
if
(
smf_n10_inst
->
get_sm_data
(
supi64
,
dnn
,
snssai
,
subscription
))
{
//update dnn_context with subscription info
sd
.
get
()
->
insert_dnn_subscription
(
snssai
,
subscription
);
//debug
//dnn_configuration_t dnn_configuration = subscription.get()->get_dnn_configuration(dnn);
//Logger::pgwc_app().debug("Retrieve Session Management Subscription data from UDM %s, %s, %s, %s", pdu_session_type_e2str[dnn_configuration.pdu_session_types.default_session_type.pdu_session_type].c_str(), ssc_mode_e2str[dnn_configuration.ssc_modes.default_ssc_mode.ssc_mode].c_str(), dnn_configuration.session_ambr.uplink.c_str(), dnn_configuration.session_ambr.downlink.c_str());
}
}
//Step 4. check the validity of the UE request, if valid send PDU Session Accept, otherwise send PDU Session Reject to AMF
//Step 5. let the context handle the message
//in this step, SMF will send N4 Session Establishment/Modification to UPF (step 10a, section 4.3.2 3GPP 23.502)
//SMF, then, sends response to AMF
sc
.
get
()
->
handle_amf_msg
(
sm_context_req_msg
,
httpResponse
);
}
src/pgwc/pgw_app.hpp
View file @
85eb18a3
...
...
@@ -28,12 +28,22 @@
#ifndef FILE_PGW_APP_HPP_SEEN
#define FILE_PGW_APP_HPP_SEEN
#include "smf.h"
#include "3gpp_29.274.h"
#include "itti_msg_s5s8.hpp"
#include "itti_msg_sxab.hpp"
#include "pgw_context.hpp"
#include "pgw_pco.hpp"
#include "SmContextCreateData.h"
#include "SmContextCreateError.h"
#include "pistache/endpoint.h"
#include "pistache/http.h"
#include "pistache/router.h"
#include "smf_msg.hpp"
extern
"C"
{
#include "sm_msg.h"
}
#include <map>
#include <set>
...
...
@@ -65,6 +75,11 @@ private:
mutable
std
::
shared_mutex
m_s5s8lteid2pgw_context
;
mutable
std
::
shared_mutex
m_seid2pgw_context
;
//for SMF
std
::
map
<
supi64_t
,
std
::
shared_ptr
<
pgw_context
>>
supi2pgw_context
;
mutable
std
::
shared_mutex
m_supi2smf_context
;
int
apply_config
(
const
pgw_config
&
cfg
);
teid_t
generate_s5s8_cp_teid
();
...
...
@@ -133,6 +148,68 @@ public:
void
handle_itti_msg
(
itti_sxab_association_setup_request
&
m
);
void
restore_sx_sessions
(
const
seid_t
&
seid
)
const
;
/*
* Handle PDUSession_CreateSMContextRequest from AMF
* @param [std::shared_ptr<pdu_session_create_sm_context_request>&] sm_context_req_msg Request message
* @param [Pistache::Http::ResponseWriter& ] httpResponse To send a response to AMF
* @return void
*/
void
handle_amf_msg
(
std
::
shared_ptr
<
pdu_session_create_sm_context_request
>&
sm_context_req_msg
,
Pistache
::
Http
::
ResponseWriter
&
httpResponse
);
/*
* Verify if SM Context is existed for this Supi
* @param [supi_t] supi
* @return True if existed, otherwise false
*/
bool
is_supi_2_smf_context
(
const
supi64_t
&
supi
)
const
;
/*
* Create/Update SMF context with the corresponding supi
* @param [supi_t] supi
* @param [std::shared_ptr<pgw_context>] sc Shared_ptr Pointer to an SMF context
* @return True if existed, otherwise false
*/
void
set_supi_2_smf_context
(
const
supi64_t
&
supi
,
std
::
shared_ptr
<
pgw_context
>
sc
);
/*
* Get SM Context
* @param [supi_t] Supi
* @return Shared pointer to SM context
*/
std
::
shared_ptr
<
pgw_context
>
supi_2_smf_context
(
const
supi64_t
&
supi
)
const
;
/*
* Check whether SMF uses local configuration instead of retrieving Session Management Data from UDM
* @param [std::string] dnn_selection_mode
* @return True if SMF uses the local configuration to check the validity of the UE request, False otherwise
*/
bool
is_use_local_configuration_subscription_data
(
const
std
::
string
&
dnn_selection_mode
);
/*
* Verify whether the Session Management Data is existed
* @param [supi_t] SUPI
* @param [std::string] DNN
* @param [snssai_t] S-NSSAI
* @return True if SMF uses the local configuration to check the validity of the UE request, False otherwise
*/
bool
is_supi_dnn_snssai_subscription_data
(
supi_t
&
supi
,
std
::
string
&
dnn
,
snssai_t
&
snssai
);
/*
* Verify whether the UE request is valid according to the user subscription and with local policies
* @param [..]
* @return True if the request is valid, otherwise False
*/
bool
is_create_sm_context_request_valid
();
/*
* Send create session response to AMF
* @param [Pistache::Http::ResponseWriter] httpResponse
* @param [ oai::smf::model::SmContextCreateError] smContextCreateError
*
*/
void
send_create_session_response
(
Pistache
::
Http
::
ResponseWriter
&
httpResponse
,
oai
::
smf
::
model
::
SmContextCreateError
&
smContextCreateError
,
Pistache
::
Http
::
Code
code
);
};
}
#include "pgw_config.hpp"
...
...
src/pgwc/pgw_config.cpp
View file @
85eb18a3
...
...
@@ -594,3 +594,25 @@ pgw_config::~pgw_config()
{
}
//------------------------------------------------------------------------------
bool
pgw_config
::
is_dotted_dnn_handled
(
const
std
::
string
&
dnn
,
const
pdu_session_type_t
&
pdn_session_type
)
{
return
true
;
//test
Logger
::
pgwc_app
().
debug
(
"DNN: %s"
,
dnn
.
c_str
());
for
(
int
i
=
0
;
i
<
pgw_cfg
.
num_apn
;
i
++
)
{
Logger
::
pgwc_app
().
debug
(
"apn_label: %s"
,
pgw_cfg
.
apn
[
i
].
apn_label
.
c_str
());
if
(
0
==
dnn
.
compare
(
pgw_cfg
.
apn
[
i
].
apn_label
))
{
if
(
pdn_session_type
.
pdu_session_type
==
pgw_cfg
.
apn
[
i
].
pdn_type
.
pdn_type
)
{
return
true
;
}
}
}
return
false
;
}
src/pgwc/pgw_config.hpp
View file @
85eb18a3
...
...
@@ -35,6 +35,8 @@
#include "pfcp.hpp"
#include "thread_sched.hpp"
#include "smf.h"
#include <arpa/inet.h>
#include <libconfig.h++>
#include <netinet/in.h>
...
...
@@ -246,6 +248,7 @@ public:
bool
is_dotted_apn_handled
(
const
std
::
string
&
apn
,
const
pdn_type_t
&
pdn_type
);
int
get_pfcp_node_id
(
pfcp
::
node_id_t
&
node_id
);
int
get_pfcp_fseid
(
pfcp
::
fseid_t
&
fseid
);
bool
is_dotted_dnn_handled
(
const
std
::
string
&
apn
,
const
pdu_session_type_t
&
pdn_session_type
);
};
}
// namespace pgw
...
...
src/pgwc/pgw_context.cpp
View file @
85eb18a3
...
...
@@ -33,6 +33,9 @@
#include "pgw_context.hpp"
#include "pgw_paa_dynamic.hpp"
#include "pgwc_procedure.hpp"
#include "ProblemDetails.h"
#include "3gpp_29.502.h"
#include <algorithm>
...
...
@@ -967,8 +970,336 @@ std::string pgw_context::toString() const
s
.
append
(
it
->
toString
());
}
//s.append("\tIMSI:\t"+toString(p.msisdn));
//apns.reserve(MAX_APN_PER_UE);
return
s
;
//s.append("\tIMSI:\t"+toString(p.msisdn));
//apns.reserve(MAX_APN_PER_UE);
return
s
;
}
//TTN
//------------------------------------------------------------------------------
void
pgw_context
::
handle_amf_msg
(
std
::
shared_ptr
<
pdu_session_create_sm_context_request
>&
sm_context_req_msg
,
Pistache
::
Http
::
ResponseWriter
&
httpResponse
)
{
Logger
::
pgwc_app
().
info
(
"Handle AMF message"
);
//Step 1. get necessary information
Logger
::
pgwc_app
().
debug
(
"Handle AMF message, supi "
SUPI_64_FMT
" "
,
sm_context_req_msg
->
get_supi
());
std
::
string
dnn
=
sm_context_req_msg
->
get_dnn
();
//oai::smf::model::Snssai snssai_sm = smContextCreateData.getSNssai();
snssai_t
snssai
=
sm_context_req_msg
->
get_snssai
();
std
::
string
requestType
=
sm_context_req_msg
->
get_request_type
();
supi_t
supi
=
sm_context_req_msg
->
get_supi
();
supi64_t
supi64
=
smf_supi_to_u64
(
supi
);
uint32_t
pdu_session_id
=
sm_context_req_msg
->
get_pdu_sessionId
();
oai
::
smf
::
model
::
SmContextCreateError
smContextCreateError
;
oai
::
smf
::
model
::
ProblemDetails
problem_details
;
bool
request_accepted
=
true
;
//problem_details.setCause()
//Step 2. check the validity of the UE request, if valid send PDU Session Accept, otherwise send PDU Session Reject to AMF
if
(
!
verify_sm_context_request
(
sm_context_req_msg
)){
//TODO: Need to implement this function
// Not a valid request...
Logger
::
pgwc_app
().
warn
(
"Received PDU_SESSION_CREATESMCONTEXT_REQUEST, the request is not valid!"
);
problem_details
.
setCause
(
pdu_session_application_error_e2str
[
PDU_SESSION_APPLICATION_ERROR_SUBSCRIPTION_DENIED
]);
//TODO: add causes to header file
smContextCreateError
.
setError
(
problem_details
);
//TODO: create a PDU Session Establishment Response by relying on NAS and assign to smContextCeateError.m_N1SmMsg
send_create_session_response_error
(
smContextCreateError
,
Pistache
::
Http
::
Code
::
Forbidden
,
httpResponse
);
return
;
}
//store HttpResponse and session-related information to be used when receiving the response from UPF
pgwc
::
pdu_session_create_sm_context_response
*
sm_context_resp
=
new
pdu_session_create_sm_context_response
(
httpResponse
);
std
::
shared_ptr
<
pdu_session_create_sm_context_response
>
sm_context_resp_pending
=
std
::
shared_ptr
<
pdu_session_create_sm_context_response
>
(
sm_context_resp
);
//step 3. find pdn_connection
std
::
shared_ptr
<
dnn_context
>
sd
;
bool
find_dnn
=
find_dnn_context
(
dnn
,
sd
);
//step 3.1. create dnn context if not exist
//At this step, this context should be existed
if
(
nullptr
==
sd
.
get
())
{
Logger
::
pgwc_app
().
debug
(
"DNN context (dnn_in_use %s) is not existed yet!"
,
dnn
.
c_str
());
dnn_context
*
d
=
new
(
dnn_context
);
d
->
in_use
=
true
;
d
->
dnn_in_use
=
dnn
;
//ambr
//insert
sd
=
std
::
shared_ptr
<
dnn_context
>
(
d
);
insert_dnn
(
sd
);
}
else
{
sd
.
get
()
->
dnn_in_use
=
dnn
;
Logger
::
pgwc_app
().
debug
(
"DNN context (dnn_in_use %s) is already existed"
,
dnn
.
c_str
());
}
//step 3.2. create pdn connection if not exist
std
::
shared_ptr
<
pgw_pdn_connection
>
sp
;
bool
find_pdn
=
sd
.
get
()
->
find_pdn_connection
(
pdu_session_id
,
sp
);
if
(
nullptr
==
sp
.
get
()){
Logger
::
pgwc_app
().
debug
(
"Create a new PDN connection!"
);
//create a new pdn connection
pgw_pdn_connection
*
p
=
new
(
pgw_pdn_connection
);
p
->
pdn_type
.
pdn_type
=
sm_context_req_msg
->
get_pdu_session_type
();
p
->
pdn_type
.
pdn_type
=
PDN_TYPE_E_IPV4
;
//TODO: should be removed after get the correct information from NAS_MSG
p
->
pdu_session_id
=
pdu_session_id
;
//should check also nas_msg.pdusessionidentity ??
//amf id
p
->
amf_id
=
sm_context_req_msg
->
get_serving_nfId
();
sp
=
std
::
shared_ptr
<
pgw_pdn_connection
>
(
p
);
sd
->
insert_pdn_connection
(
sp
);
}
else
{
Logger
::
pgwc_app
().
debug
(
"PDN connection is already existed!"
);
//TODO:
}
//pending session??