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
79655dbd
Commit
79655dbd
authored
Mar 26, 2019
by
gauthier
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
prepare handling of SPGW-U Failure in PGW-C 3GPP TS 23.007 (17.1A.4 PGW-U Failure)
parent
6a68aff2
Changes
7
Show whitespace changes
Inline
Side-by-side
Showing
7 changed files
with
912 additions
and
15 deletions
+912
-15
src/oai_spgwc/CMakeLists.txt
src/oai_spgwc/CMakeLists.txt
+4
-4
src/pgwc/pgw_pfcp_association.cpp
src/pgwc/pgw_pfcp_association.cpp
+257
-0
src/pgwc/pgw_pfcp_association.hpp
src/pgwc/pgw_pfcp_association.hpp
+144
-0
src/pgwc/pgwc_sxab.cpp
src/pgwc/pgwc_sxab.cpp
+492
-0
src/spgwu/spgwu_pfcp_association.cpp
src/spgwu/spgwu_pfcp_association.cpp
+2
-2
src/spgwu/spgwu_pfcp_association.hpp
src/spgwu/spgwu_pfcp_association.hpp
+11
-7
src/spgwu/spgwu_sx.hpp
src/spgwu/spgwu_sx.hpp
+2
-2
No files found.
src/oai_spgwc/CMakeLists.txt
View file @
79655dbd
...
...
@@ -310,5 +310,5 @@ if(${SGW_AUTOTEST})
SET
(
GTPV1U_LIB GTPV1U
)
endif
(
${
SGW_AUTOTEST
}
)
target_link_libraries
(
spgwc
${
ASAN
}
-Wl,--start-group CN_UTILS SGWC PGWC
${
GTPV1U_LIB
}
GTPV2C PFCP 3GPP_COMMON_TYPES -Wl,--end-group pthread m rt config++ event boost_system
)
target_link_libraries
(
spgwc
${
ASAN
}
-Wl,--start-group CN_UTILS SGWC PGWC
${
GTPV1U_LIB
}
GTPV2C PFCP 3GPP_COMMON_TYPES
gflags glog dl double-conversion folly
-Wl,--end-group pthread m rt config++ event boost_system
)
src/pgwc/pgw_pfcp_association.cpp
0 → 100644
View file @
79655dbd
/*
* 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 spgwu_pfcp_association.cpp
\brief
\author Lionel GAUTHIER
\date 2019
\email: lionel.gauthier@eurecom.fr
*/
#include "common_defs.h"
#include "logger.hpp"
#include "pgw_pfcp_association.hpp"
#include "pgwc_sxab.hpp"
using
namespace
oai
::
cn
::
core
;
using
namespace
oai
::
cn
::
core
::
itti
;
using
namespace
oai
::
cn
::
nf
::
pgwc
;
using
namespace
std
;
extern
itti_mw
*
itti_inst
;
extern
pgwc_sxab
*
pgwc_sxab_inst
;
//------------------------------------------------------------------------------
void
pfcp_association
::
notify_add_session
(
const
oai
::
cn
::
core
::
pfcp
::
fseid_t
&
cp_fseid
)
{
std
::
unique_lock
<
std
::
mutex
>
l
(
m_sessions
);
sessions
.
insert
(
cp_fseid
);
}
//------------------------------------------------------------------------------
bool
pfcp_association
::
has_session
(
const
oai
::
cn
::
core
::
pfcp
::
fseid_t
&
cp_fseid
)
{
std
::
unique_lock
<
std
::
mutex
>
l
(
m_sessions
);
auto
it
=
sessions
.
find
(
cp_fseid
);
if
(
it
!=
sessions
.
end
())
{
return
true
;
}
else
{
return
false
;
}
}
//------------------------------------------------------------------------------
void
pfcp_association
::
notify_del_session
(
const
oai
::
cn
::
core
::
pfcp
::
fseid_t
&
cp_fseid
)
{
std
::
unique_lock
<
std
::
mutex
>
l
(
m_sessions
);
sessions
.
erase
(
cp_fseid
);
}
// //------------------------------------------------------------------------------
// void pfcp_association::del_sessions()
// {
// std::unique_lock<std::mutex> l(m_sessions);
// for (std::set<core::pfcp::fseid_t>::iterator it=sessions.begin(); it!=sessions.end();) {
// ???->remove_pfcp_session(*it);
// sessions.erase(it++);
// }
// }
//------------------------------------------------------------------------------
void
pfcp_association
::
restore_sx_sessions
()
{
std
::
unique_lock
<
std
::
mutex
>
l
(
m_sessions
);
for
(
std
::
set
<
core
::
pfcp
::
fseid_t
>::
iterator
it
=
sessions
.
begin
();
it
!=
sessions
.
end
();)
{
;
}
}
//------------------------------------------------------------------------------
bool
pfcp_associations
::
add_association
(
oai
::
cn
::
core
::
pfcp
::
node_id_t
&
node_id
,
oai
::
cn
::
core
::
pfcp
::
recovery_time_stamp_t
&
recovery_time_stamp
,
bool
&
restore_sx_sessions
)
{
std
::
shared_ptr
<
pfcp_association
>
sa
=
std
::
shared_ptr
<
pfcp_association
>
(
nullptr
);
if
(
get_association
(
node_id
,
sa
))
{
itti_inst
->
timer_remove
(
sa
->
timer_heartbeat
);
if
(
sa
->
recovery_time_stamp
==
recovery_time_stamp
)
{
restore_sx_sessions
=
false
;
}
else
{
restore_sx_sessions
=
true
;
}
sa
->
recovery_time_stamp
=
recovery_time_stamp
;
sa
->
function_features
=
{};
}
else
{
restore_sx_sessions
=
false
;
pfcp_association
*
association
=
new
pfcp_association
(
node_id
,
recovery_time_stamp
);
sa
=
std
::
shared_ptr
<
pfcp_association
>
(
association
);
sa
->
recovery_time_stamp
=
recovery_time_stamp
;
std
::
size_t
hash_node_id
=
std
::
hash
<
oai
::
cn
::
core
::
pfcp
::
node_id_t
>
{}(
node_id
);
associations
.
insert
((
int32_t
)
hash_node_id
,
sa
);
trigger_heartbeat_request_procedure
(
sa
);
}
return
true
;
}
//------------------------------------------------------------------------------
bool
pfcp_associations
::
add_association
(
oai
::
cn
::
core
::
pfcp
::
node_id_t
&
node_id
,
oai
::
cn
::
core
::
pfcp
::
recovery_time_stamp_t
&
recovery_time_stamp
,
oai
::
cn
::
core
::
pfcp
::
up_function_features_s
&
function_features
,
bool
&
restore_sx_sessions
)
{
std
::
shared_ptr
<
pfcp_association
>
sa
=
std
::
shared_ptr
<
pfcp_association
>
(
nullptr
);
if
(
get_association
(
node_id
,
sa
))
{
itti_inst
->
timer_remove
(
sa
->
timer_heartbeat
);
if
(
sa
->
recovery_time_stamp
==
recovery_time_stamp
)
{
restore_sx_sessions
=
false
;
}
else
{
restore_sx_sessions
=
true
;
}
sa
->
recovery_time_stamp
=
recovery_time_stamp
;
sa
->
function_features
.
first
=
true
;
sa
->
function_features
.
second
=
function_features
;
}
else
{
restore_sx_sessions
=
false
;
pfcp_association
*
association
=
new
pfcp_association
(
node_id
,
recovery_time_stamp
,
function_features
);
sa
=
std
::
shared_ptr
<
pfcp_association
>
(
association
);
sa
->
recovery_time_stamp
=
recovery_time_stamp
;
sa
->
function_features
.
first
=
true
;
sa
->
function_features
.
second
=
function_features
;
std
::
size_t
hash_node_id
=
std
::
hash
<
oai
::
cn
::
core
::
pfcp
::
node_id_t
>
{}(
node_id
);
associations
.
insert
((
int32_t
)
hash_node_id
,
sa
);
trigger_heartbeat_request_procedure
(
sa
);
}
return
true
;
}
//------------------------------------------------------------------------------
bool
pfcp_associations
::
get_association
(
const
oai
::
cn
::
core
::
pfcp
::
node_id_t
&
node_id
,
std
::
shared_ptr
<
pfcp_association
>&
sa
)
const
{
std
::
size_t
hash_node_id
=
std
::
hash
<
oai
::
cn
::
core
::
pfcp
::
node_id_t
>
{}(
node_id
);
auto
pit
=
associations
.
find
((
int32_t
)
hash_node_id
);
if
(
pit
==
associations
.
end
()
)
return
false
;
else
{
sa
=
pit
->
second
;
return
true
;
}
}
//------------------------------------------------------------------------------
bool
pfcp_associations
::
get_association
(
const
oai
::
cn
::
core
::
pfcp
::
fseid_t
&
cp_fseid
,
std
::
shared_ptr
<
pfcp_association
>&
sa
)
const
{
folly
::
AtomicHashMap
<
int32_t
,
std
::
shared_ptr
<
pfcp_association
>>::
iterator
it
;
FOR_EACH
(
it
,
associations
)
{
std
::
shared_ptr
<
pfcp_association
>
a
=
it
->
second
;
if
(
it
->
second
->
has_session
(
cp_fseid
))
{
sa
=
it
->
second
;
return
true
;
}
}
return
false
;
}
//------------------------------------------------------------------------------
void
pfcp_associations
::
restore_sx_sessions
(
const
oai
::
cn
::
core
::
pfcp
::
node_id_t
&
node_id
)
{
std
::
shared_ptr
<
pfcp_association
>
sa
=
{};
if
(
get_association
(
node_id
,
sa
))
{
sa
->
restore_sx_sessions
();
}
}
//------------------------------------------------------------------------------
void
pfcp_associations
::
trigger_heartbeat_request_procedure
(
std
::
shared_ptr
<
pfcp_association
>&
s
)
{
s
->
timer_heartbeat
=
itti_inst
->
timer_setup
(
PFCP_ASSOCIATION_HEARTBEAT_INTERVAL_SEC
,
0
,
TASK_PGWC_SX
,
TASK_PGWC_SX_TRIGGER_HEARTBEAT_REQUEST
,
s
->
hash_node_id
);
}
//------------------------------------------------------------------------------
void
pfcp_associations
::
initiate_heartbeat_request
(
core
::
itti
::
timer_id_t
timer_id
,
uint64_t
arg2_user
)
{
size_t
hash_node_id
=
(
size_t
)
arg2_user
;
auto
pit
=
associations
.
find
((
int32_t
)
hash_node_id
);
if
(
pit
==
associations
.
end
()
)
return
;
else
{
Logger
::
pgwc_sx
().
info
(
"PFCP HEARTBEAT PROCEDURE hash %u starting"
,
hash_node_id
);
pit
->
second
->
num_retries_timer_heartbeat
=
0
;
pgwc_sxab_inst
->
send_heartbeat_request
(
pit
->
second
);
}
}
//------------------------------------------------------------------------------
void
pfcp_associations
::
timeout_heartbeat_request
(
core
::
itti
::
timer_id_t
timer_id
,
uint64_t
arg2_user
)
{
size_t
hash_node_id
=
(
size_t
)
arg2_user
;
auto
pit
=
associations
.
find
((
int32_t
)
hash_node_id
);
if
(
pit
==
associations
.
end
()
)
return
;
else
{
if
(
pit
->
second
->
num_retries_timer_heartbeat
<
PFCP_ASSOCIATION_HEARTBEAT_MAX_RETRIES
)
{
Logger
::
pgwc_sx
().
info
(
"PFCP HEARTBEAT PROCEDURE hash %u TIMED OUT (retrie %d)"
,
hash_node_id
,
pit
->
second
->
num_retries_timer_heartbeat
);
pit
->
second
->
num_retries_timer_heartbeat
++
;
pgwc_sxab_inst
->
send_heartbeat_request
(
pit
->
second
);
}
else
{
Logger
::
pgwc_sx
().
warn
(
"PFCP HEARTBEAT PROCEDURE FAILED after %d retries! TODO"
,
PFCP_ASSOCIATION_HEARTBEAT_MAX_RETRIES
);
}
}
}
//------------------------------------------------------------------------------
void
pfcp_associations
::
handle_receive_heartbeat_response
(
const
uint64_t
trxn_id
)
{
folly
::
AtomicHashMap
<
int32_t
,
std
::
shared_ptr
<
pfcp_association
>>::
iterator
it
;
FOR_EACH
(
it
,
associations
)
{
std
::
shared_ptr
<
pfcp_association
>
a
=
it
->
second
;
if
(
it
->
second
->
trxn_id_heartbeat
==
trxn_id
)
{
itti_inst
->
timer_remove
(
it
->
second
->
timer_heartbeat
);
trigger_heartbeat_request_procedure
(
it
->
second
);
return
;
}
}
}
//------------------------------------------------------------------------------
bool
pfcp_associations
::
select_up_node
(
oai
::
cn
::
core
::
pfcp
::
node_id_t
&
node_id
,
const
int
node_selection_criteria
)
{
node_id
=
{};
if
(
associations
.
empty
())
{
return
false
;
}
folly
::
AtomicHashMap
<
int32_t
,
std
::
shared_ptr
<
pfcp_association
>>::
iterator
it
;
FOR_EACH
(
it
,
associations
)
{
std
::
shared_ptr
<
pfcp_association
>
a
=
it
->
second
;
// TODO
switch
(
node_selection_criteria
)
{
case
NODE_SELECTION_CRITERIA_BEST_MAX_HEARBEAT_RTT
:
case
NODE_SELECTION_CRITERIA_MIN_PFCP_SESSIONS
:
case
NODE_SELECTION_CRITERIA_MIN_UP_TIME
:
case
NODE_SELECTION_CRITERIA_MAX_AVAILABLE_BW
:
case
NODE_SELECTION_CRITERIA_NONE
:
default:
node_id
=
it
->
second
->
node_id
;
return
true
;
break
;
}
}
return
false
;
}
//------------------------------------------------------------------------------
void
pfcp_associations
::
notify_add_session
(
const
oai
::
cn
::
core
::
pfcp
::
node_id_t
&
node_id
,
const
oai
::
cn
::
core
::
pfcp
::
fseid_t
&
cp_fseid
)
{
std
::
shared_ptr
<
pfcp_association
>
sa
=
{};
if
(
get_association
(
node_id
,
sa
))
{
sa
->
notify_add_session
(
cp_fseid
);
}
}
//------------------------------------------------------------------------------
void
pfcp_associations
::
notify_del_session
(
const
oai
::
cn
::
core
::
pfcp
::
fseid_t
&
cp_fseid
)
{
std
::
shared_ptr
<
pfcp_association
>
sa
=
{};
if
(
get_association
(
cp_fseid
,
sa
))
{
sa
->
notify_del_session
(
cp_fseid
);
}
}
src/pgwc/pgw_pfcp_association.hpp
0 → 100644
View file @
79655dbd
/*
* 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 pgw_pfcp_association.hpp
\author Lionel GAUTHIER
\date 2019
\email: lionel.gauthier@eurecom.fr
*/
#ifndef FILE_PGW_PFCP_ASSOCIATION_HPP_SEEN
#define FILE_PGW_PFCP_ASSOCIATION_HPP_SEEN
#include "3gpp_29.244.h"
#include "itti.hpp"
#include <folly/AtomicHashMap.h>
#include <vector>
namespace
oai
::
cn
::
nf
::
pgwc
{
#define PFCP_ASSOCIATION_HEARTBEAT_INTERVAL_SEC 10
#define PFCP_ASSOCIATION_HEARTBEAT_MAX_RETRIES 2
class
pfcp_association
{
public:
oai
::
cn
::
core
::
pfcp
::
node_id_t
node_id
;
std
::
size_t
hash_node_id
;
oai
::
cn
::
core
::
pfcp
::
recovery_time_stamp_t
recovery_time_stamp
;
std
::
pair
<
bool
,
oai
::
cn
::
core
::
pfcp
::
up_function_features_s
>
function_features
;
//
mutable
std
::
mutex
m_sessions
;
std
::
set
<
oai
::
cn
::
core
::
pfcp
::
fseid_t
>
sessions
;
//
oai
::
cn
::
core
::
itti
::
timer_id_t
timer_heartbeat
;
int
num_retries_timer_heartbeat
;
uint64_t
trxn_id_heartbeat
;
oai
::
cn
::
core
::
itti
::
timer_id_t
timer_association
;
explicit
pfcp_association
(
const
oai
::
cn
::
core
::
pfcp
::
node_id_t
&
node_id
)
:
node_id
(
node_id
),
recovery_time_stamp
(),
function_features
(),
m_sessions
(),
sessions
()
{
hash_node_id
=
std
::
hash
<
oai
::
cn
::
core
::
pfcp
::
node_id_t
>
{}(
node_id
);
timer_heartbeat
=
ITTI_INVALID_TIMER_ID
;
num_retries_timer_heartbeat
=
0
;
trxn_id_heartbeat
=
0
;
}
pfcp_association
(
const
oai
::
cn
::
core
::
pfcp
::
node_id_t
&
node_id
,
oai
::
cn
::
core
::
pfcp
::
recovery_time_stamp_t
&
recovery_time_stamp
)
:
node_id
(
node_id
),
recovery_time_stamp
(
recovery_time_stamp
),
function_features
(),
m_sessions
(),
sessions
()
{
hash_node_id
=
std
::
hash
<
oai
::
cn
::
core
::
pfcp
::
node_id_t
>
{}(
node_id
);
timer_heartbeat
=
ITTI_INVALID_TIMER_ID
;
num_retries_timer_heartbeat
=
0
;
trxn_id_heartbeat
=
0
;
}
pfcp_association
(
const
oai
::
cn
::
core
::
pfcp
::
node_id_t
&
ni
,
oai
::
cn
::
core
::
pfcp
::
recovery_time_stamp_t
&
rts
,
oai
::
cn
::
core
::
pfcp
::
up_function_features_s
&
uff
)
:
node_id
(
ni
),
recovery_time_stamp
(
rts
),
m_sessions
(),
sessions
()
{
hash_node_id
=
std
::
hash
<
oai
::
cn
::
core
::
pfcp
::
node_id_t
>
{}(
node_id
);
function_features
.
first
=
true
;
function_features
.
second
=
uff
;
timer_heartbeat
=
ITTI_INVALID_TIMER_ID
;
num_retries_timer_heartbeat
=
0
;
trxn_id_heartbeat
=
0
;
timer_association
=
{};
}
pfcp_association
(
pfcp_association
const
&
p
)
:
node_id
(
p
.
node_id
),
hash_node_id
(
p
.
hash_node_id
),
recovery_time_stamp
(
p
.
recovery_time_stamp
),
function_features
(
p
.
function_features
),
timer_heartbeat
(
p
.
timer_heartbeat
),
num_retries_timer_heartbeat
(
p
.
num_retries_timer_heartbeat
),
trxn_id_heartbeat
(
p
.
trxn_id_heartbeat
),
timer_association
(
0
)
{}
void
notify_add_session
(
const
oai
::
cn
::
core
::
pfcp
::
fseid_t
&
cp_fseid
);
bool
has_session
(
const
oai
::
cn
::
core
::
pfcp
::
fseid_t
&
cp_fseid
);
void
notify_del_session
(
const
oai
::
cn
::
core
::
pfcp
::
fseid_t
&
cp_fseid
);
//void del_sessions();
void
restore_sx_sessions
();
void
set
(
const
oai
::
cn
::
core
::
pfcp
::
up_function_features_s
&
ff
)
{
function_features
.
first
=
true
;
function_features
.
second
=
ff
;};
};
enum
node_selection_criteria_e
{
NODE_SELECTION_CRITERIA_BEST_MAX_HEARBEAT_RTT
=
0
,
NODE_SELECTION_CRITERIA_MIN_PFCP_SESSIONS
=
1
,
NODE_SELECTION_CRITERIA_MIN_UP_TIME
=
2
,
NODE_SELECTION_CRITERIA_MAX_AVAILABLE_BW
=
3
,
NODE_SELECTION_CRITERIA_NONE
=
4
};
#define PFCP_MAX_ASSOCIATIONS 16
class
pfcp_associations
{
private:
std
::
vector
<
std
::
shared_ptr
<
pfcp_association
>>
pending_associations
;
folly
::
AtomicHashMap
<
int32_t
,
std
::
shared_ptr
<
pfcp_association
>>
associations
;
pfcp_associations
()
:
associations
(
PFCP_MAX_ASSOCIATIONS
),
pending_associations
()
{};
void
trigger_heartbeat_request_procedure
(
std
::
shared_ptr
<
pfcp_association
>&
s
);
public:
static
pfcp_associations
&
get_instance
()
{
static
pfcp_associations
instance
;
return
instance
;
}
pfcp_associations
(
pfcp_associations
const
&
)
=
delete
;
void
operator
=
(
pfcp_associations
const
&
)
=
delete
;
bool
add_association
(
oai
::
cn
::
core
::
pfcp
::
node_id_t
&
node_id
,
oai
::
cn
::
core
::
pfcp
::
recovery_time_stamp_t
&
recovery_time_stamp
,
bool
&
restore_sx_sessions
);
bool
add_association
(
oai
::
cn
::
core
::
pfcp
::
node_id_t
&
node_id
,
oai
::
cn
::
core
::
pfcp
::
recovery_time_stamp_t
&
recovery_time_stamp
,
oai
::
cn
::
core
::
pfcp
::
up_function_features_s
&
function_features
,
bool
&
restore_sx_sessions
);
bool
get_association
(
const
oai
::
cn
::
core
::
pfcp
::
node_id_t
&
node_id
,
std
::
shared_ptr
<
pfcp_association
>&
sa
)
const
;
bool
get_association
(
const
oai
::
cn
::
core
::
pfcp
::
fseid_t
&
cp_fseid
,
std
::
shared_ptr
<
pfcp_association
>&
sa
)
const
;
void
notify_add_session
(
const
oai
::
cn
::
core
::
pfcp
::
node_id_t
&
node_id
,
const
oai
::
cn
::
core
::
pfcp
::
fseid_t
&
cp_fseid
);
void
notify_del_session
(
const
oai
::
cn
::
core
::
pfcp
::
fseid_t
&
cp_fseid
);
void
restore_sx_sessions
(
const
oai
::
cn
::
core
::
pfcp
::
node_id_t
&
node_id
);
void
initiate_heartbeat_request
(
oai
::
cn
::
core
::
itti
::
timer_id_t
timer_id
,
uint64_t
arg2_user
);
void
timeout_heartbeat_request
(
oai
::
cn
::
core
::
itti
::
timer_id_t
timer_id
,
uint64_t
arg2_user
);
void
handle_receive_heartbeat_response
(
const
uint64_t
trxn_id
);
bool
select_up_node
(
oai
::
cn
::
core
::
pfcp
::
node_id_t
&
node_id
,
const
int
node_selection_criteria
);
};
}
#endif
/* FILE_PGW_PFCP_ASSOCIATION_HPP_SEEN */
src/pgwc/pgwc_sxab.cpp
0 → 100644
View file @
79655dbd
/*
* 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 pgwc_sxab.cpp
\brief
\author Lionel Gauthier
\company Eurecom
\email: lionel.gauthier@eurecom.fr
*/
#include "common_defs.h"
#include "itti.hpp"
#include "logger.hpp"
#include "pgw_config.hpp"
#include "pgwc_sxab.hpp"
#include <chrono>
#include <ctime>
#include <stdexcept>
using
namespace
oai
::
cn
::
core
;
using
namespace
oai
::
cn
::
proto
::
pfcp
;
using
namespace
oai
::
cn
::
core
::
itti
;
using
namespace
oai
::
cn
::
nf
::
pgwc
;
using
namespace
std
;
extern
itti_mw
*
itti_inst
;
extern
pgw_config
pgw_cfg
;
extern
pgwc_sxab
*
pgwc_sxab_inst
;
void
pgwc_sxab_task
(
void
*
);
//------------------------------------------------------------------------------
void
pgwc_sxab_task
(
void
*
args_p
)
{
const
task_id_t
task_id
=
TASK_PGWC_SX
;
itti_inst
->
notify_task_ready
(
task_id
);
do
{
std
::
shared_ptr
<
itti_msg
>
shared_msg
=
itti_inst
->
receive_msg
(
task_id
);
auto
*
msg
=
shared_msg
.
get
();
switch
(
msg
->
msg_type
)
{
case
SXAB_HEARTBEAT_REQUEST
:
if
(
itti_sxab_heartbeat_request
*
m
=
dynamic_cast
<
itti_sxab_heartbeat_request
*>
(
msg
))
{
pgwc_sxab_inst
->
handle_itti_msg
(
ref
(
*
m
));
}
break
;
case
SXAB_HEARTBEAT_RESPONSE
:
if
(
itti_sxab_heartbeat_response
*
m
=
dynamic_cast
<
itti_sxab_heartbeat_response
*>
(
msg
))
{
pgwc_sxab_inst
->
handle_itti_msg
(
ref
(
*
m
));
}
break
;
case
SXAB_ASSOCIATION_SETUP_REQUEST
:
if
(
itti_sxab_association_setup_request
*
m
=
dynamic_cast
<
itti_sxab_association_setup_request
*>
(
msg
))
{
pgwc_sxab_inst
->
handle_itti_msg
(
ref
(
*
m
));
}
break
;
case
SXAB_ASSOCIATION_SETUP_RESPONSE
:
if
(
itti_sxab_association_setup_response
*
m
=
dynamic_cast
<
itti_sxab_association_setup_response
*>
(
msg
))
{
pgwc_sxab_inst
->
handle_itti_msg
(
ref
(
*
m
));
}
break
;
case
SXAB_ASSOCIATION_UPDATE_REQUEST
:
if
(
itti_sxab_association_update_request
*
m
=
dynamic_cast
<
itti_sxab_association_update_request
*>
(
msg
))
{
pgwc_sxab_inst
->
handle_itti_msg
(
ref
(
*
m
));
}
break
;
case
SXAB_ASSOCIATION_UPDATE_RESPONSE
:
if
(
itti_sxab_association_update_response
*
m
=
dynamic_cast
<
itti_sxab_association_update_response
*>
(
msg
))
{
pgwc_sxab_inst
->
handle_itti_msg
(
ref
(
*
m
));
}
break
;
case
SXAB_ASSOCIATION_RELEASE_REQUEST
:
if
(
itti_sxab_association_release_request
*
m
=
dynamic_cast
<
itti_sxab_association_release_request
*>
(
msg
))
{
pgwc_sxab_inst
->
handle_itti_msg
(
ref
(
*
m
));
}
break
;
case
SXAB_ASSOCIATION_RELEASE_RESPONSE
:
if
(
itti_sxab_association_release_response
*
m
=
dynamic_cast
<
itti_sxab_association_release_response
*>
(
msg
))
{
pgwc_sxab_inst
->
handle_itti_msg
(
ref
(
*
m
));
}
break
;
case
SXAB_VERSION_NOT_SUPPORTED_RESPONSE
:
if
(
itti_sxab_version_not_supported_response
*
m
=
dynamic_cast
<
itti_sxab_version_not_supported_response
*>
(
msg
))
{
pgwc_sxab_inst
->
handle_itti_msg
(
ref
(
*
m
));
}
break
;
case
SXAB_NODE_REPORT_RESPONSE
:
if
(
itti_sxab_node_report_response
*
m
=
dynamic_cast
<
itti_sxab_node_report_response
*>
(
msg
))
{
pgwc_sxab_inst
->
handle_itti_msg
(
ref
(
*
m
));
}
break
;
case
SXAB_SESSION_SET_DELETION_REQUEST
:
if
(
itti_sxab_session_set_deletion_request
*
m
=
dynamic_cast
<
itti_sxab_session_set_deletion_request
*>
(
msg
))
{
pgwc_sxab_inst
->
handle_itti_msg
(
ref
(
*
m
));
}
break
;
case
SXAB_SESSION_ESTABLISHMENT_REQUEST
:
if
(
itti_sxab_session_establishment_request
*
m
=
dynamic_cast
<
itti_sxab_session_establishment_request
*>
(
msg
))
{
pgwc_sxab_inst
->
send_sx_msg
(
ref
(
*
m
));
}
break
;
case
SXAB_SESSION_MODIFICATION_REQUEST
:
if
(
itti_sxab_session_modification_request
*
m
=
dynamic_cast
<
itti_sxab_session_modification_request
*>
(
msg
))
{
pgwc_sxab_inst
->
send_sx_msg
(
ref
(
*
m
));
}
break
;
case
SXAB_SESSION_DELETION_REQUEST
:
if
(
itti_sxab_session_deletion_request
*
m
=
dynamic_cast
<
itti_sxab_session_deletion_request
*>
(
msg
))
{
pgwc_sxab_inst
->
send_sx_msg
(
ref
(
*
m
));
}
break
;
case
SXAB_SESSION_REPORT_RESPONSE
:
if
(
itti_sxab_session_report_response
*
m
=
dynamic_cast
<
itti_sxab_session_report_response
*>
(
msg
))
{
pgwc_sxab_inst
->
handle_itti_msg
(
ref
(
*
m
));
}
break
;
case
TIME_OUT
:
if
(
itti_msg_timeout
*
to
=
dynamic_cast
<
itti_msg_timeout
*>
(
msg
))
{
Logger
::
pgwc_sx
().
info
(
"TIME-OUT event timer id %d"
,
to
->
timer_id
);
switch
(
to
->
arg1_user
)
{
case
TASK_PGWC_SX_TRIGGER_HEARTBEAT_REQUEST
:
pfcp_associations
::
get_instance
().
initiate_heartbeat_request
(
to
->
timer_id
,
to
->
arg2_user
);
break
;
case
TASK_PGWC_SX_TIMEOUT_HEARTBEAT_REQUEST
:
pfcp_associations
::
get_instance
().
timeout_heartbeat_request
(
to
->
timer_id
,
to
->
arg2_user
);
break
;
default:
;
}
}
break
;
case
TERMINATE
:
if
(
itti_msg_terminate
*
terminate
=
dynamic_cast
<
itti_msg_terminate
*>
(
msg
))
{
Logger
::
pgwc_sx
().
info
(
"Received terminate message"
);
return
;
}
break
;
default:
Logger
::
pgwc_sx
().
info
(
"no handler for msg type %d"
,
msg
->
msg_type
);
}
}
while
(
true
);
}
//------------------------------------------------------------------------------
pgwc_sxab
::
pgwc_sxab
()
:
pfcp_l4_stack
(
string
(
inet_ntoa
(
pgw_cfg
.
sx
.
addr4
)),
pgw_cfg
.
sx
.
port
)
{
Logger
::
pgwc_sx
().
startup
(
"Starting..."
);
// TODO refine this, look at RFC5905
std
::
tm
tm_epoch
=
{
0
};
// Feb 8th, 2036
tm_epoch
.
tm_year
=
2036
-
1900
;
// years count from 1900
tm_epoch
.
tm_mon
=
2
-
1
;
// months count from January=0
tm_epoch
.
tm_mday
=
8
;
// days count from 1
std
::
time_t
time_epoch
=
std
::
mktime
(
&
tm_epoch
);
std
::
chrono
::
time_point
<
std
::
chrono
::
system_clock
>
now
=
std
::
chrono
::
system_clock
::
now
();
std
::
time_t
now_c
=
std
::
chrono
::
system_clock
::
to_time_t
(
now
);
std
::
time_t
ellapsed
=
now_c
-
time_epoch
;
recovery_time_stamp
=
ellapsed
;
// TODO may load this from config
cp_function_features
=
{};
cp_function_features
.
ovrl
=
0
;
cp_function_features
.
load
=
0
;
if
(
itti_inst
->
create_task
(
TASK_PGWC_SX
,
pgwc_sxab_task
,
nullptr
)
)
{
Logger
::
pgwc_sx
().
error
(
"Cannot create task TASK_PGWC_SX"
);
throw
std
::
runtime_error
(
"Cannot create task TASK_PGWC_SX"
);
}
Logger
::
pgwc_sx
().
startup
(
"Started"
);
}
//------------------------------------------------------------------------------
void
pgwc_sxab
::
handle_receive_pfcp_msg
(
pfcp_msg
&
msg
,
const
boost
::
asio
::
ip
::
udp
::
endpoint
&
remote_endpoint
)
{
Logger
::
pgwc_sx
().
trace
(
"handle_receive_pfcp_msg msg type %d length %d"
,
msg
.
get_message_type
(),
msg
.
get_message_length
());
switch
(
msg
.
get_message_type
())
{
case
PFCP_ASSOCIATION_SETUP_REQUEST
:
handle_receive_association_setup_request
(
msg
,
remote_endpoint
);
break
;
case
PFCP_HEARTBEAT_REQUEST
:
handle_receive_heartbeat_request
(
msg
,
remote_endpoint
);
break
;
case
PFCP_HEARTBEAT_RESPONSE
:
handle_receive_heartbeat_response
(
msg
,
remote_endpoint
);
break
;
case
PFCP_SESSION_ESTABLISHMENT_RESPONSE
:
handle_receive_session_establishment_response
(
msg
,
remote_endpoint
);
break
;
case
PFCP_SESSION_MODIFICATION_RESPONSE
:
handle_receive_session_modification_response
(
msg
,
remote_endpoint
);
break
;
case
PFCP_SESSION_DELETION_RESPONSE
:
handle_receive_session_deletion_response
(
msg
,
remote_endpoint
);
break
;
case
PFCP_PFCP_PFD_MANAGEMENT_REQUEST
:
case
PFCP_PFCP_PFD_MANAGEMENT_RESPONSE
:
case
PFCP_ASSOCIATION_SETUP_RESPONSE
:
case
PFCP_ASSOCIATION_UPDATE_REQUEST
:
case
PFCP_ASSOCIATION_UPDATE_RESPONSE
:
case
PFCP_ASSOCIATION_RELEASE_REQUEST
:
case
PFCP_ASSOCIATION_RELEASE_RESPONSE
:
case
PFCP_VERSION_NOT_SUPPORTED_RESPONSE
:
case
PFCP_NODE_REPORT_REQUEST
:
case
PFCP_NODE_REPORT_RESPONSE
:
case
PFCP_SESSION_SET_DELETION_REQUEST
:
case
PFCP_SESSION_SET_DELETION_RESPONSE
:
case
PFCP_SESSION_ESTABLISHMENT_REQUEST
:
case
PFCP_SESSION_MODIFICATION_REQUEST
:
case
PFCP_SESSION_DELETION_REQUEST
:
case
PFCP_SESSION_REPORT_REQUEST
:
case
PFCP_SESSION_REPORT_RESPONSE
:
Logger
::
pgwc_sx
().
info
(
"handle_receive_pfcp_msg msg %d length %d, not handled, discarded!"
,
msg
.
get_message_type
(),
msg
.
get_message_length
());
break
;
default:
Logger
::
pgwc_sx
().
info
(
"handle_receive_pfcp_msg msg %d length %d, unknown, discarded!"
,
msg
.
get_message_type
(),
msg
.
get_message_length
());
}
}
//------------------------------------------------------------------------------
void
pgwc_sxab
::
handle_receive_heartbeat_request
(
proto
::
pfcp
::
pfcp_msg
&
msg
,
const
boost
::
asio
::
ip
::
udp
::
endpoint
&
remote_endpoint
)
{
bool
error
=
true
;
uint64_t
trxn_id
=
0
;
pfcp_heartbeat_request
msg_ies_container
=
{};
msg
.
to_core_type
(
msg_ies_container
);
handle_receive_message_cb
(
msg
,
remote_endpoint
,
TASK_PGWC_SX
,
error
,
trxn_id
);
if
(
!
error
)
{
if
(
not
msg_ies_container
.
recovery_time_stamp
.
first
)
{
// Should be detected by lower layers
Logger
::
pgwc_sx
().
warn
(
"Received SX HEARTBEAT REQUEST without recovery time stamp IE!, ignore message"
);
return
;
}
send_heartbeat_response
(
remote_endpoint
,
trxn_id
);
}
}
//------------------------------------------------------------------------------
void
pgwc_sxab
::
handle_receive_heartbeat_response
(
proto
::
pfcp
::
pfcp_msg
&
msg
,
const
boost
::
asio
::
ip
::
udp
::
endpoint
&
remote_endpoint
)
{
bool
error
=
true
;
uint64_t
trxn_id
=
0
;
pfcp_heartbeat_response
msg_ies_container
=
{};
msg
.
to_core_type
(
msg_ies_container
);
handle_receive_message_cb
(
msg
,
remote_endpoint
,
TASK_PGWC_SX
,
error
,
trxn_id
);
if
(
!
error
)
{
if
(
not
msg_ies_container
.
recovery_time_stamp
.
first
)
{
// Should be detected by lower layers
Logger
::
pgwc_sx
().
warn
(
"Received SX HEARTBEAT REQUEST without recovery time stamp IE!, ignore message"
);
return
;
}
pfcp_associations
::
get_instance
().
handle_receive_heartbeat_response
(
trxn_id
);
}
}
//------------------------------------------------------------------------------
void
pgwc_sxab
::
handle_receive_association_setup_request
(
proto
::
pfcp
::
pfcp_msg
&
msg
,
const
boost
::
asio
::
ip
::
udp
::
endpoint
&
remote_endpoint
)
{
bool
error
=
true
;
uint64_t
trxn_id
=
0
;
pfcp_association_setup_request
msg_ies_container
=
{};
msg
.
to_core_type
(
msg_ies_container
);
handle_receive_message_cb
(
msg
,
remote_endpoint
,
TASK_PGWC_SX
,
error
,
trxn_id
);
if
(
!
error
)
{
if
(
not
msg_ies_container
.
node_id
.
first
)
{
// Should be detected by lower layers
Logger
::
pgwc_sx
().
warn
(
"Received SX ASSOCIATION SETUP REQUEST without node id IE!, ignore message"
);
return
;
}
if
(
not
msg_ies_container
.
recovery_time_stamp
.
first
)
{
// Should be detected by lower layers
Logger
::
pgwc_sx
().
warn
(
"Received SX ASSOCIATION SETUP REQUEST without recovery time stamp IE!, ignore message"
);
return
;
}
bool
restore_sx_sessions
=
false
;
if
(
msg_ies_container
.
up_function_features
.
first
)
{
// Should be detected by lower layers
pfcp_associations
::
get_instance
().
add_association
(
msg_ies_container
.
node_id
.
second
,
msg_ies_container
.
recovery_time_stamp
.
second
,
msg_ies_container
.
up_function_features
.
second
,
restore_sx_sessions
);
}
else
{
pfcp_associations
::
get_instance
().
add_association
(
msg_ies_container
.
node_id
.
second
,
msg_ies_container
.
recovery_time_stamp
.
second
,
restore_sx_sessions
);
}
// always yes (for the time being)
itti_sxab_association_setup_response
a
(
TASK_SPGWU_SX
,
TASK_SPGWU_SX
);
a
.
trxn_id
=
trxn_id
;
oai
::
cn
::
core
::
pfcp
::
cause_t
cause
=
{.
cause_value
=
oai
::
cn
::
core
::
pfcp
::
CAUSE_VALUE_REQUEST_ACCEPTED
};
a
.
pfcp_ies
.
set
(
cause
);
oai
::
cn
::
core
::
pfcp
::
node_id_t
node_id
=
{};
if
(
pgw_cfg
.
get_pfcp_node_id
(
node_id
)
==
RETURNok
)
{
a
.
pfcp_ies
.
set
(
node_id
);
core
::
pfcp
::
recovery_time_stamp_t
r
=
{.
recovery_time_stamp
=
(
uint32_t
)
recovery_time_stamp
};
a
.
pfcp_ies
.
set
(
r
);
a
.
pfcp_ies
.
set
(
cp_function_features
);
if
(
node_id
.
node_id_type
==
core
::
pfcp
::
NODE_ID_TYPE_IPV4_ADDRESS
)
{
//a.l_endpoint = boost::asio::ip::udp::endpoint(boost::asio::ip::address_v4(pgw_cfg.sx.addr4), 0);
a
.
r_endpoint
=
remote_endpoint
;
send_sx_msg
(
a
);
}
else
{
Logger
::
pgwc_sx
().
warn
(
"Received SX ASSOCIATION SETUP REQUEST TODO node_id IPV6, FQDN!, ignore message"
);
return
;
}
}
else
{
Logger
::
pgwc_sx
().
warn
(
"Received SX ASSOCIATION SETUP REQUEST could not set node id!, ignore message"
);
return
;
}
if
(
restore_sx_sessions
)
{
pfcp_associations
::
get_instance
().
restore_sx_sessions
(
msg_ies_container
.
node_id
.
second
);
}
}
}
//------------------------------------------------------------------------------
void
pgwc_sxab
::
handle_receive_session_establishment_response
(
proto
::
pfcp
::
pfcp_msg
&
msg
,
const
boost
::
asio
::
ip
::
udp
::
endpoint
&
remote_endpoint
)
{
bool
error
=
true
;
uint64_t
trxn_id
=
0
;
pfcp_session_establishment_response
msg_ies_container
=
{};
msg
.
to_core_type
(
msg_ies_container
);
handle_receive_message_cb
(
msg
,
remote_endpoint
,
TASK_PGWC_SX
,
error
,
trxn_id
);
if
(
!
error
)
{
itti_sxab_session_establishment_response
*
itti_msg
=
new
itti_sxab_session_establishment_response
(
TASK_PGWC_SX
,
TASK_PGWC_APP
);
itti_msg
->
pfcp_ies
=
msg_ies_container
;
itti_msg
->
r_endpoint
=
remote_endpoint
;
itti_msg
->
trxn_id
=
trxn_id
;
itti_msg
->
seid
=
msg
.
get_seid
();
std
::
shared_ptr
<
itti_sxab_session_establishment_response
>
i
=
std
::
shared_ptr
<
itti_sxab_session_establishment_response
>
(
itti_msg
);
int
ret
=
itti_inst
->
send_msg
(
i
);
if
(
RETURNok
!=
ret
)
{
Logger
::
pgwc_sx
().
error
(
"Could not send ITTI message %s to task TASK_PGWC_APP"
,
i
->
get_msg_name
());
}
}
// else ignore
}
//------------------------------------------------------------------------------
void
pgwc_sxab
::
handle_receive_session_modification_response
(
proto
::
pfcp
::
pfcp_msg
&
msg
,
const
boost
::
asio
::
ip
::
udp
::
endpoint
&
remote_endpoint
)
{
bool
error
=
true
;
uint64_t
trxn_id
=
0
;
pfcp_session_modification_response
msg_ies_container
=
{};
msg
.
to_core_type
(
msg_ies_container
);
handle_receive_message_cb
(
msg
,
remote_endpoint
,
TASK_PGWC_SX
,
error
,
trxn_id
);
if
(
!
error
)
{
itti_sxab_session_modification_response
*
itti_msg
=
new
itti_sxab_session_modification_response
(
TASK_PGWC_SX
,
TASK_PGWC_APP
);
itti_msg
->
pfcp_ies
=
msg_ies_container
;
itti_msg
->
r_endpoint
=
remote_endpoint
;
itti_msg
->
trxn_id
=
trxn_id
;
itti_msg
->
seid
=
msg
.
get_seid
();
std
::
shared_ptr
<
itti_sxab_session_modification_response
>
i
=
std
::
shared_ptr
<
itti_sxab_session_modification_response
>
(
itti_msg
);
int
ret
=
itti_inst
->
send_msg
(
i
);
if
(
RETURNok
!=
ret
)
{
Logger
::
pgwc_sx
().
error
(
"Could not send ITTI message %s to task TASK_PGWC_APP"
,
i
->
get_msg_name
());
}
}
// else ignore
}
//------------------------------------------------------------------------------
void
pgwc_sxab
::
handle_receive_session_deletion_response
(
proto
::
pfcp
::
pfcp_msg
&
msg
,
const
boost
::
asio
::
ip
::
udp
::
endpoint
&
remote_endpoint
)
{
bool
error
=
true
;
uint64_t
trxn_id
=
0
;
pfcp_session_deletion_response
msg_ies_container
=
{};
msg
.
to_core_type
(
msg_ies_container
);
handle_receive_message_cb
(
msg
,
remote_endpoint
,
TASK_PGWC_SX
,
error
,
trxn_id
);
if
(
!
error
)
{
itti_sxab_session_deletion_response
*
itti_msg
=
new
itti_sxab_session_deletion_response
(
TASK_PGWC_SX
,
TASK_PGWC_APP
);
itti_msg
->
pfcp_ies
=
msg_ies_container
;
itti_msg
->
r_endpoint
=
remote_endpoint
;
itti_msg
->
trxn_id
=
trxn_id
;
itti_msg
->
seid
=
msg
.
get_seid
();
std
::
shared_ptr
<
itti_sxab_session_deletion_response
>
i
=
std
::
shared_ptr
<
itti_sxab_session_deletion_response
>
(
itti_msg
);
int
ret
=
itti_inst
->
send_msg
(
i
);
if
(
RETURNok
!=
ret
)
{
Logger
::
pgwc_sx
().
error
(
"Could not send ITTI message %s to task TASK_PGWC_APP"
,
i
->
get_msg_name
());
}
}
// else ignore
}
//------------------------------------------------------------------------------
void
pgwc_sxab
::
send_sx_msg
(
itti_sxab_association_setup_response
&
i
)
{
send_response
(
i
.
r_endpoint
,
i
.
pfcp_ies
,
i
.
trxn_id
);
}
//------------------------------------------------------------------------------
void
pgwc_sxab
::
send_heartbeat_request
(
std
::
shared_ptr
<
pfcp_association
>&
a
)
{
oai
::
cn
::
proto
::
pfcp
::
pfcp_heartbeat_request
h
=
{};
core
::
pfcp
::
recovery_time_stamp_t
r
=
{.
recovery_time_stamp
=
(
uint32_t
)
recovery_time_stamp
};
h
.
set
(
r
);
core
::
pfcp
::
node_id_t
&
node_id
=
a
->
node_id
;
if
(
node_id
.
node_id_type
==
core
::
pfcp
::
NODE_ID_TYPE_IPV4_ADDRESS
)
{
a
->
timer_heartbeat
=
itti_inst
->
timer_setup
(
5
,
0
,
TASK_PGWC_SX
,
TASK_PGWC_SX_TIMEOUT_HEARTBEAT_REQUEST
,
a
->
hash_node_id
);
boost
::
asio
::
ip
::
udp
::
endpoint
r_endpoint
=
boost
::
asio
::
ip
::
udp
::
endpoint
(
boost
::
asio
::
ip
::
address_v4
(
htobe32
(
node_id
.
u1
.
ipv4_address
.
s_addr
)),
8805
);
a
->
trxn_id_heartbeat
=
generate_trxn_id
();
send_request
(
r_endpoint
,
h
,
TASK_PGWC_SX
,
a
->
trxn_id_heartbeat
);
}
else
{
Logger
::
pgwc_sx
().
warn
(
"TODO send_heartbeat_request() node_id IPV6, FQDN!"
);
}
}
//------------------------------------------------------------------------------
void
pgwc_sxab
::
send_heartbeat_response
(
const
boost
::
asio
::
ip
::
udp
::
endpoint
&
r_endpoint
,
const
uint64_t
trxn_id
)
{
oai
::
cn
::
proto
::
pfcp
::
pfcp_heartbeat_response
h
=
{};
core
::
pfcp
::
recovery_time_stamp_t
r
=
{.
recovery_time_stamp
=
(
uint32_t
)
recovery_time_stamp
};
h
.
set
(
r
);
send_response
(
r_endpoint
,
h
,
trxn_id
);
}
//------------------------------------------------------------------------------
void
pgwc_sxab
::
send_sx_msg
(
itti_sxab_session_establishment_request
&
i
)
{
send_request
(
i
.
r_endpoint
,
i
.
seid
,
i
.
pfcp_ies
,
TASK_PGWC_SX
,
i
.
trxn_id
);
}
//------------------------------------------------------------------------------
void
pgwc_sxab
::
send_sx_msg
(
itti_sxab_session_modification_request
&
i
)
{
send_request
(
i
.
r_endpoint
,
i
.
seid
,
i
.
pfcp_ies
,
TASK_PGWC_SX
,
i
.
trxn_id
);
}
//------------------------------------------------------------------------------
void
pgwc_sxab
::
send_sx_msg
(
itti_sxab_session_deletion_request
&
i
)
{
send_request
(
i
.
r_endpoint
,
i
.
seid
,
i
.
pfcp_ies
,
TASK_PGWC_SX
,
i
.
trxn_id
);
}
//------------------------------------------------------------------------------
void
pgwc_sxab
::
handle_receive
(
char
*
recv_buffer
,
const
std
::
size_t
bytes_transferred
,
boost
::
asio
::
ip
::
udp
::
endpoint
&
remote_endpoint
)
{
Logger
::
pgwc_sx
().
info
(
"handle_receive(%d bytes)"
,
bytes_transferred
);
//std::cout << string_to_hex(recv_buffer, bytes_transferred) << std::endl;
std
::
istringstream
iss
(
std
::
istringstream
::
binary
);
iss
.
rdbuf
()
->
pubsetbuf
(
recv_buffer
,
bytes_transferred
);
pfcp_msg
msg
=
{};
msg
.
remote_port
=
remote_endpoint
.
port
();
try
{
msg
.
load_from
(
iss
);
handle_receive_pfcp_msg
(
msg
,
remote_endpoint
);
}
catch
(
pfcp_exception
&
e
)
{
Logger
::
pgwc_sx
().
info
(
"handle_receive exception %s"
,
e
.
what
());
}
}
//------------------------------------------------------------------------------
void
pgwc_sxab
::
time_out_itti_event
(
const
uint32_t
timer_id
)
{
bool
handled
=
false
;
time_out_event
(
timer_id
,
TASK_PGWC_SX
,
handled
);
if
(
!
handled
)
{
Logger
::
pgwc_sx
().
error
(
"Timer %d not Found"
,
timer_id
);
}
}
src/spgwu/spgwu_pfcp_association.cpp
View file @
79655dbd
...
...
@@ -87,7 +87,7 @@ bool pfcp_associations::add_association(oai::cn::core::pfcp::node_id_t& node_id,
return
false
;
}
//------------------------------------------------------------------------------
bool
pfcp_associations
::
add_association
(
oai
::
cn
::
core
::
pfcp
::
node_id_t
&
node_id
,
oai
::
cn
::
core
::
pfcp
::
recovery_time_stamp_t
&
recovery_time_stamp
,
oai
::
cn
::
core
::
pfcp
::
cp_function_features_
t
&
bool
pfcp_associations
::
add_association
(
oai
::
cn
::
core
::
pfcp
::
node_id_t
&
node_id
,
oai
::
cn
::
core
::
pfcp
::
recovery_time_stamp_t
&
recovery_time_stamp
,
oai
::
cn
::
core
::
pfcp
::
cp_function_features_
s
&
function_features
)
{
std
::
shared_ptr
<
pfcp_association
>
sa
=
{};
...
...
src/spgwu/spgwu_pfcp_association.hpp
View file @
79655dbd
...
...
@@ -44,7 +44,7 @@ namespace oai::cn::nf::spgwu {
oai
::
cn
::
core
::
pfcp
::
node_id_t
node_id
;
std
::
size_t
hash_node_id
;
oai
::
cn
::
core
::
pfcp
::
recovery_time_stamp_t
recovery_time_stamp
;
std
::
pair
<
bool
,
oai
::
cn
::
core
::
pfcp
::
cp_function_features_
t
>
function_features
;
std
::
pair
<
bool
,
oai
::
cn
::
core
::
pfcp
::
cp_function_features_
s
>
function_features
;
//
mutable
std
::
mutex
m_sessions
;
std
::
set
<
oai
::
cn
::
core
::
pfcp
::
fseid_t
>
sessions
;
...
...
@@ -69,7 +69,7 @@ namespace oai::cn::nf::spgwu {
num_retries_timer_heartbeat
=
0
;
trxn_id_heartbeat
=
0
;
}
pfcp_association
(
const
oai
::
cn
::
core
::
pfcp
::
node_id_t
&
ni
,
oai
::
cn
::
core
::
pfcp
::
recovery_time_stamp_t
&
rts
,
oai
::
cn
::
core
::
pfcp
::
cp_function_features_
t
&
uff
)
:
pfcp_association
(
const
oai
::
cn
::
core
::
pfcp
::
node_id_t
&
ni
,
oai
::
cn
::
core
::
pfcp
::
recovery_time_stamp_t
&
rts
,
oai
::
cn
::
core
::
pfcp
::
cp_function_features_
s
&
uff
)
:
node_id
(
ni
),
recovery_time_stamp
(
rts
),
m_sessions
(),
sessions
()
{
hash_node_id
=
std
::
hash
<
oai
::
cn
::
core
::
pfcp
::
node_id_t
>
{}(
node_id
);
function_features
.
first
=
true
;
...
...
@@ -77,6 +77,7 @@ namespace oai::cn::nf::spgwu {
timer_heartbeat
=
ITTI_INVALID_TIMER_ID
;
num_retries_timer_heartbeat
=
0
;
trxn_id_heartbeat
=
0
;
timer_association
=
{};
}
// pfcp_association(pfcp_association const & p)
// {
...
...
@@ -94,7 +95,7 @@ namespace oai::cn::nf::spgwu {
bool
has_session
(
const
oai
::
cn
::
core
::
pfcp
::
fseid_t
&
cp_fseid
);
void
notify_del_session
(
const
oai
::
cn
::
core
::
pfcp
::
fseid_t
&
cp_fseid
);
void
del_sessions
();
void
set
(
const
oai
::
cn
::
core
::
pfcp
::
cp_function_features_
t
&
ff
)
{
function_features
.
first
=
true
;
function_features
.
second
=
ff
;};
void
set
(
const
oai
::
cn
::
core
::
pfcp
::
cp_function_features_
s
&
ff
)
{
function_features
.
first
=
true
;
function_features
.
second
=
ff
;};
};
#define PFCP_MAX_ASSOCIATIONS 16
...
...
@@ -119,7 +120,7 @@ namespace oai::cn::nf::spgwu {
void
operator
=
(
pfcp_associations
const
&
)
=
delete
;
bool
add_association
(
oai
::
cn
::
core
::
pfcp
::
node_id_t
&
node_id
,
oai
::
cn
::
core
::
pfcp
::
recovery_time_stamp_t
&
recovery_time_stamp
);
bool
add_association
(
oai
::
cn
::
core
::
pfcp
::
node_id_t
&
node_id
,
oai
::
cn
::
core
::
pfcp
::
recovery_time_stamp_t
&
recovery_time_stamp
,
oai
::
cn
::
core
::
pfcp
::
cp_function_features_
t
&
function_features
);
bool
add_association
(
oai
::
cn
::
core
::
pfcp
::
node_id_t
&
node_id
,
oai
::
cn
::
core
::
pfcp
::
recovery_time_stamp_t
&
recovery_time_stamp
,
oai
::
cn
::
core
::
pfcp
::
cp_function_features_
s
&
function_features
);
bool
get_association
(
const
oai
::
cn
::
core
::
pfcp
::
node_id_t
&
node_id
,
std
::
shared_ptr
<
pfcp_association
>&
sa
)
const
;
bool
get_association
(
const
oai
::
cn
::
core
::
pfcp
::
fseid_t
&
cp_fseid
,
std
::
shared_ptr
<
pfcp_association
>&
sa
)
const
;
...
...
@@ -127,6 +128,9 @@ namespace oai::cn::nf::spgwu {
void
notify_del_session
(
const
oai
::
cn
::
core
::
pfcp
::
fseid_t
&
cp_fseid
);
bool
add_peer_candidate_node
(
const
oai
::
cn
::
core
::
pfcp
::
node_id_t
&
node_id
);
void
restore_sx_sessions
(
const
oai
::
cn
::
core
::
pfcp
::
node_id_t
&
node_id
);
void
initiate_heartbeat_request
(
oai
::
cn
::
core
::
itti
::
timer_id_t
timer_id
,
uint64_t
arg2_user
);
void
timeout_heartbeat_request
(
oai
::
cn
::
core
::
itti
::
timer_id_t
timer_id
,
uint64_t
arg2_user
);
...
...
src/spgwu/spgwu_sx.hpp
View file @
79655dbd
...
...
@@ -50,7 +50,7 @@ private:
std
::
thread
thread
;
uint64_t
recovery_time_stamp
;
//timestamp in seconds
core
::
pfcp
::
up_function_features_
t
up_function_features
;
core
::
pfcp
::
up_function_features_
s
up_function_features
;
void
start_association
(
const
core
::
pfcp
::
node_id_t
&
node_id
);
...
...
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