Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
O
OpenXG-SMF
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Issues
0
Issues
0
List
Boards
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Operations
Operations
Metrics
Environments
Analytics
Analytics
CI / CD
Repository
Value Stream
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
OpenXG
OpenXG-SMF
Commits
dd0fcfc4
Commit
dd0fcfc4
authored
Jun 14, 2022
by
Stefan Spettel
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
feat(pcf): Added policy association to PDU session
Signed-off-by:
Stefan Spettel
<
stefan.spettel@eurecom.fr
>
parent
4ca31398
Changes
6
Show whitespace changes
Inline
Side-by-side
Showing
6 changed files
with
179 additions
and
21 deletions
+179
-21
src/smf_app/smf_context.cpp
src/smf_app/smf_context.cpp
+12
-6
src/smf_app/smf_context.hpp
src/smf_app/smf_context.hpp
+3
-0
src/smf_app/smf_n7.cpp
src/smf_app/smf_n7.cpp
+42
-9
src/smf_app/smf_n7.hpp
src/smf_app/smf_n7.hpp
+45
-6
src/smf_app/smf_sbi.cpp
src/smf_app/smf_sbi.cpp
+60
-0
src/smf_app/smf_sbi.hpp
src/smf_app/smf_sbi.hpp
+17
-0
No files found.
src/smf_app/smf_context.cpp
View file @
dd0fcfc4
...
...
@@ -451,6 +451,12 @@ std::string smf_pdu_session::toString() const {
}
}
}
if
(
policy_ptr
)
{
s
.
append
(
"
\t
Policy Decision:"
).
append
(
"
\n
"
);
s
.
append
(
policy_ptr
->
toString
());
}
return
s
;
}
...
...
@@ -1502,21 +1508,21 @@ void smf_context::handle_pdu_session_create_sm_context_request(
// Step 5. Create SM Policy Association with PCF or local PCC rules
std
::
string
smContextRef
=
std
::
to_string
(
smreq
->
scid
);
oai
::
smf_server
::
model
::
SmPolicyDecision
policy_decision
;
n7
::
policy_association
policy_ass
;
sp
.
get
()
->
policy_ptr
=
std
::
make_shared
<
n7
::
policy_association
>
();
bool
use_pcf_policy
=
false
;
if
(
!
smf_cfg
.
use_local_pcc_rules
)
{
policy_ass
.
set_context
(
sp
.
get
()
->
policy_ptr
->
set_context
(
smf_supi_to_string
(
smreq
->
req
.
get_supi
()),
smreq
->
req
.
get_dnn
(),
snssai
,
plmn
,
smreq
->
req
.
get_pdu_session_id
(),
smreq
->
req
.
get_pdu_session_type
());
// TODO what is the exact meaning of SCID? Is this unique per registration
// or unique per PDU session?
policy_ass
.
id
=
smreq
->
scid
;
sp
.
get
()
->
policy_ptr
->
id
=
smreq
->
scid
;
n7
::
sm_policy_status_code
status
=
n7
::
smf_n7
::
get_instance
().
create_sm_policy_association
(
policy_ass
);
n7
::
smf_n7
::
get_instance
().
create_sm_policy_association
(
*
sp
->
policy_ptr
);
if
(
status
!=
n7
::
sm_policy_status_code
::
CREATED
)
{
Logger
::
smf_n7
().
info
(
"PCF SM Policy Association Creation was not successful. Continue "
...
...
src/smf_app/smf_context.hpp
View file @
dd0fcfc4
...
...
@@ -46,6 +46,7 @@
#include "smf_event.hpp"
#include "smf_procedure.hpp"
#include "uint_generator.hpp"
#include "smf_n7.hpp"
extern
"C"
{
#include "Ngap_PDUSessionAggregateMaximumBitRate.h"
...
...
@@ -560,6 +561,8 @@ class smf_pdu_session : public std::enable_shared_from_this<smf_pdu_session> {
bool
released
;
// release session request
std
::
shared_ptr
<
n7
::
policy_association
>
policy_ptr
;
uint32_t
pdu_session_id
;
std
::
string
dnn
;
// associated DNN
snssai_t
snssai
;
// associated SNSSAI
...
...
src/smf_app/smf_n7.cpp
View file @
dd0fcfc4
...
...
@@ -33,6 +33,9 @@
#include "nlohmann/json.hpp"
#include "3gpp_29.500.h"
#include "ProblemDetails.h"
#include "uint_generator.hpp"
#include <regex>
using
namespace
smf
;
using
namespace
smf
::
n7
;
...
...
@@ -61,9 +64,13 @@ uint32_t smf_n7::select_pcf(const SmPolicyContextData& context) {
policy_storages
.
insert
(
1
,
storage
);
return
1
;
// ID is always 1, only one PF
}
else
{
return
-
1
;
Logger
::
smf_n7
().
info
(
"Did not find PCF"
);
return
0
;
}
}
// TODO for now, only use first PCF
return
1
;
}
sm_policy_status_code
smf_n7
::
create_sm_policy_association
(
...
...
@@ -87,9 +94,22 @@ sm_policy_status_code smf_n7::create_sm_policy_association(
return
sm_policy_status_code
::
PCF_NOT_AVAILABLE
;
}
return
it
->
second
->
create_policy_association
(
association
);
sm_policy_status_code
res
=
it
->
second
->
create_policy_association
(
association
);
if
(
res
==
sm_policy_status_code
::
CREATED
)
{
if
(
association
.
id
==
0
)
{
association
.
id
=
util
::
uint_uid_generator
<
uint64_t
>::
get_instance
().
get_uid
();
}
association
.
pcf_id
=
pcf_id
;
Logger
::
smf_n7
().
debug
(
"Successfully created policy association with ID: %lu "
,
association
.
id
);
}
// return store->create_policy_association(association)
;
return
res
;
}
smf_n7
::~
smf_n7
()
{
...
...
@@ -183,6 +203,7 @@ sm_policy_status_code smf_pcf_client::create_policy_association(
Logger
::
smf_n7
().
info
(
"Sending PCF SM policy association creation request"
);
std
::
string
response_data
;
std
::
string
response_headers
;
// generate a promise for the curl handle
uint32_t
promise_id
=
smf_sbi_inst
->
generate_promise_id
();
...
...
@@ -197,8 +218,8 @@ sm_policy_status_code smf_pcf_client::create_policy_association(
// Create a new curl easy handle and add to the multi handle
if
(
!
smf_sbi_inst
->
curl_create_handle
(
root_uri
,
json_data
.
dump
(),
response_data
,
pid_ptr
,
"POST"
,
smf_cfg
.
http_version
))
{
root_uri
,
json_data
.
dump
(),
response_data
,
response_headers
,
pid_ptr
,
"POST"
,
smf_cfg
.
http_version
))
{
Logger
::
smf_sbi
().
warn
(
"Could not create a new handle to send message to PCF"
);
smf_sbi_inst
->
remove_promise
(
promise_id
);
...
...
@@ -213,10 +234,22 @@ sm_policy_status_code smf_pcf_client::create_policy_association(
Logger
::
smf_sbi
().
debug
(
"Response data %s"
,
response_data
.
c_str
());
if
(
response_code
==
http_status_code_e
::
HTTP_STATUS_CODE_201_CREATED
)
{
from_json
(
response_data
,
association
.
decision
);
std
::
regex
rgx
(
"Location: *(.*)"
);
std
::
smatch
match
;
if
(
std
::
regex_search
(
response_headers
,
match
,
rgx
))
{
association
.
pcf_location
=
match
[
1
];
nlohmann
::
json
j
=
nlohmann
::
json
::
parse
(
response_data
);
from_json
(
j
,
association
.
decision
);
Logger
::
smf_n7
().
info
(
"Successfully created SM Policy Association for SUPI %s"
,
association
.
context
.
getSupi
().
c_str
());
}
else
{
Logger
::
smf_n7
().
debug
(
"SM Policy Association response does not contain Location!"
);
return
sm_policy_status_code
::
INTERNAL_ERROR
;
}
return
sm_policy_status_code
::
CREATED
;
}
...
...
src/smf_app/smf_n7.hpp
View file @
dd0fcfc4
...
...
@@ -66,8 +66,8 @@ enum class sm_policy_status_code {
struct
policy_association
{
oai
::
smf_server
::
model
::
SmPolicyDecision
decision
;
oai
::
smf_server
::
model
::
SmPolicyContextData
context
;
uint
32_t
id
=
-
1
;
uint
32_t
pcf_id
=
-
1
;
uint
64_t
id
=
0
;
uint
64_t
pcf_id
=
0
;
std
::
string
pcf_location
;
void
set_context
(
...
...
@@ -96,6 +96,23 @@ struct policy_association {
context
.
setPduSessionType
(
pdu_session_type_model
);
context
.
setDnn
(
dnn
);
}
std
::
string
toString
()
{
std
::
string
s
=
""
;
if
(
decision
.
pccRulesIsSet
())
{
s
.
append
(
"
\t\t
PCC Rules:
\n
"
);
for
(
auto
it
:
decision
.
getPccRules
())
{
s
.
append
(
"
\t\t\t\t
"
).
append
(
it
.
second
.
getPccRuleId
()).
append
(
"
\n
"
);
}
}
if
(
decision
.
traffContDecsIsSet
())
{
s
.
append
(
"
\t\t
Traffic Control Descriptions:
\n
"
);
for
(
auto
it
:
decision
.
getTraffContDecs
())
{
s
.
append
(
"
\t\t\t\t
"
).
append
(
it
.
second
.
getTcId
()).
append
(
"
\n
"
);
}
}
return
s
;
}
};
/**
...
...
@@ -231,10 +248,9 @@ class smf_pcf_client : public policy_storage {
*/
class
smf_n7
{
public:
const
uint32_t
ASSOCIATIONS_SIZE
=
1024
;
const
uint32_t
PCF_CLIENTS
=
16
;
smf_n7
()
:
associations
(
ASSOCIATIONS_SIZE
),
policy_storages
(
PCF_CLIENTS
){};
smf_n7
()
:
policy_storages
(
PCF_CLIENTS
){};
smf_n7
(
smf_n7
const
&
)
=
delete
;
void
operator
=
(
smf_n7
const
&
)
=
delete
;
virtual
~
smf_n7
();
...
...
@@ -261,6 +277,30 @@ class smf_n7 {
sm_policy_status_code
create_sm_policy_association
(
policy_association
&
association
);
/**
* @brief Removes an SM Policy Association on the PCF. The params pcf_id and
* id of the association parameter need to be set
*
* @param association input: pcf_id and id need to be set and exist
* @return sm_policy_status_code OK in case of success, otherwise NOT_FOUND,
* INTERNAL_ERROR, PCF_NOT_AVAILABLE
*/
sm_policy_status_code
remove_sm_policy_association
(
const
policy_association
&
association
);
/**
* @brief Updates an SM Policy Association, requires the triggers to be set as
* defined in 3GPP TS 29.512
*
* @param association The association to update
* @param update_data The update context data
* @return sm_policy_status_code OK in case of success, otherwise NOT_FOUND,
* INTERNAL_ERROR, PCF_NOT_AVAILABLE
*/
sm_policy_status_code
update_sm_policy_association
(
policy_association
&
association
,
const
oai
::
smf_server
::
model
::
SmPolicyUpdateContextData
&
update_data
);
private:
/**
* @brief Allows the discovery of a PCF, either via NRF or local
...
...
@@ -279,7 +319,6 @@ class smf_n7 {
// amount of objects is known upfront.
folly
::
AtomicHashMap
<
uint32_t
,
std
::
shared_ptr
<
policy_storage
>>
policy_storages
;
folly
::
AtomicHashMap
<
uint32_t
,
smf
::
n7
::
policy_association
>
associations
;
};
}
// namespace smf::n7
#endif
/* FILE_SMF_N4_HPP_SEEN */
src/smf_app/smf_sbi.cpp
View file @
dd0fcfc4
...
...
@@ -1198,6 +1198,66 @@ bool smf_sbi::curl_create_handle(
return
true
;
}
// TODO we should not repeat ourselves... propose to make a private function
// which does curl_init
//------------------------------------------------------------------------------
bool
smf_sbi
::
curl_create_handle
(
const
std
::
string
&
uri
,
const
std
::
string
&
data
,
std
::
string
&
response_data
,
std
::
string
&
response_headers
,
uint32_t
*
promise_id
,
const
std
::
string
&
method
,
uint8_t
http_version
)
{
// Create handle for a curl request
CURL
*
curl
=
curl_easy_init
();
if
((
curl
==
nullptr
)
or
(
headers
==
nullptr
))
{
Logger
::
smf_sbi
().
error
(
"Cannot initialize a new Curl Handle"
);
return
false
;
}
curl_easy_setopt
(
curl
,
CURLOPT_HTTPHEADER
,
headers
);
curl_easy_setopt
(
curl
,
CURLOPT_URL
,
uri
.
c_str
());
// curl_easy_setopt(curl, CURLOPT_VERBOSE, 0L);
curl_easy_setopt
(
curl
,
CURLOPT_PRIVATE
,
promise_id
);
if
(
method
.
compare
(
"POST"
)
==
0
)
curl_easy_setopt
(
curl
,
CURLOPT_POST
,
1
);
else
if
(
method
.
compare
(
"PATCH"
)
==
0
)
curl_easy_setopt
(
curl
,
CURLOPT_CUSTOMREQUEST
,
"PATCH"
);
else
if
(
method
.
compare
(
"PUT"
)
==
0
)
curl_easy_setopt
(
curl
,
CURLOPT_CUSTOMREQUEST
,
"PUT"
);
else
curl_easy_setopt
(
curl
,
CURLOPT_HTTPGET
,
1
);
curl_easy_setopt
(
curl
,
CURLOPT_TIMEOUT_MS
,
NF_CURL_TIMEOUT_MS
);
curl_easy_setopt
(
curl
,
CURLOPT_INTERFACE
,
smf_cfg
.
sbi
.
if_name
.
c_str
());
if
(
http_version
==
2
)
{
curl_easy_setopt
(
curl
,
CURLOPT_VERBOSE
,
1L
);
// We use a self-signed test server, skip verification during debugging
curl_easy_setopt
(
curl
,
CURLOPT_SSL_VERIFYPEER
,
0L
);
curl_easy_setopt
(
curl
,
CURLOPT_SSL_VERIFYHOST
,
0L
);
curl_easy_setopt
(
curl
,
CURLOPT_HTTP_VERSION
,
CURL_HTTP_VERSION_2_PRIOR_KNOWLEDGE
);
}
// Hook up data handling function.
curl_easy_setopt
(
curl
,
CURLOPT_WRITEFUNCTION
,
&
callback
);
curl_easy_setopt
(
curl
,
CURLOPT_WRITEDATA
,
&
response_data
);
curl_easy_setopt
(
curl
,
CURLOPT_WRITEHEADER
,
&
response_headers
);
curl_easy_setopt
(
curl
,
CURLOPT_FOLLOWLOCATION
,
1L
);
if
(
method
.
compare
(
"DELETE"
)
!=
0
)
{
curl_easy_setopt
(
curl
,
CURLOPT_POSTFIELDSIZE
,
data
.
length
());
curl_easy_setopt
(
curl
,
CURLOPT_POSTFIELDS
,
data
.
c_str
());
}
// Add to the multi handle
curl_multi_add_handle
(
curl_multi
,
curl
);
handles
.
push_back
(
curl
);
// Curl cmd will actually be performed in perform_curl_multi
perform_curl_multi
(
0
);
// TODO: current time as parameter if curl is performed per event
return
true
;
}
//------------------------------------------------------------------------------
bool
smf_sbi
::
curl_create_handle
(
const
std
::
string
&
uri
,
std
::
string
&
response_data
,
uint32_t
*
promise_id
,
...
...
src/smf_app/smf_sbi.hpp
View file @
dd0fcfc4
...
...
@@ -199,6 +199,23 @@ class smf_sbi {
std
::
string
&
response_data
,
uint32_t
*
promise_id
,
const
std
::
string
&
method
,
uint8_t
http_version
=
1
);
/*
* Create Curl handle for multi curl with support of response headers
* @param [const std::string &] uri: URI of the subscribed NF
* @param [const std::string& ] data: data to be sent
* @param [std::string &] response_data: response data
* @param [std::string &] response_headers: all response headers
* @param [uint32_t* ] promise_id: pointer to the promise id
* @param [const std::string&] method: HTTP method
* @param [bool] is_multipart: use multipart or json format
* @return true if a handle was created successfully, otherwise return false
*/
bool
curl_create_handle
(
const
std
::
string
&
uri
,
const
std
::
string
&
data
,
std
::
string
&
response_data
,
std
::
string
&
response_headers
,
uint32_t
*
promise_id
,
const
std
::
string
&
method
,
uint8_t
http_version
=
1
);
/*
* Create Curl handle for multi curl
* @param [const std::string &] uri: URI of the subscribed NF
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment