fixeria submitted this change.

View Change

Approvals: laforge: Looks good to me, but someone else must approve pespin: Looks good to me, approved Jenkins Builder: Verified
pfcp_peer: implement the Heartbeat procedure

Change-Id: Ic4682d49f2e1df08d241500b7b4e75edadaeb91a
---
M src/pfcp_peer.erl
1 file changed, 32 insertions(+), 3 deletions(-)

diff --git a/src/pfcp_peer.erl b/src/pfcp_peer.erl
index b190f12..8c29a9f 100644
--- a/src/pfcp_peer.erl
+++ b/src/pfcp_peer.erl
@@ -169,7 +169,8 @@
%% Handle incoming PFCP PDU(s)
connecting(info, {udp, Sock, FromIp, FromPort, Data},
#peer_state{sock = Sock} = S) ->
- case decode_pdu(Data, {FromIp, FromPort}, S) of
+ PDU = decode_pdu(Data, {FromIp, FromPort}, S),
+ case PDU of
#pfcp{type = association_setup_response,
ie = #{pfcp_cause := 'Request accepted',
recovery_time_stamp := #recovery_time_stamp{time = RRTS}}} ->
@@ -180,7 +181,13 @@
ie = #{pfcp_cause := Cause}} ->
?LOG_ERROR("Rx Association Setup Response (~p)", [Cause]),
{stop, {shutdown, assoc_setup_nack}};
- PDU ->
+ %% 3GPP TS 29.244, 6.2.2.2 Heartbeat Request
+ %% A CP function or UP function shall be prepared to receive a Heartbeat Request
+ %% at any time (even from unknown peers) and it shall reply with a Heartbeat Response.
+ #pfcp{type = heartbeat_request} ->
+ recv_heartbeat_request(PDU, {FromIp, FromPort}, S),
+ {keep_state, S};
+ _ ->
?LOG_NOTICE("Rx unexpected PFCP PDU: ~p", [PDU]),
{keep_state, S}
end;
@@ -216,7 +223,13 @@
connected(info, {udp, Sock, FromIp, FromPort, Data},
#peer_state{sock = Sock} = S) ->
PDU = decode_pdu(Data, {FromIp, FromPort}, S),
- route_pdu(PDU, S),
+ case PDU of
+ %% 3GPP TS 29.244, 6.2.2.2 Heartbeat Request
+ #pfcp{type = heartbeat_request} ->
+ recv_heartbeat_request(PDU, {FromIp, FromPort}, S);
+ _ ->
+ route_pdu(PDU, S)
+ end,
{keep_state, S};

%% Catch-all handler for this state
@@ -409,4 +422,20 @@
send_session_delete_req(SEID, S) ->
send_pdu(SEID, {session_deletion_request, []}, S).

+
+%% 6.2.2 Heartbeat Procedure
+%% 7.4.2 Heartbeat Messages
+recv_heartbeat_request(#pfcp{type = heartbeat_request,
+ seq_no = SeqNr,
+ ie = ReqIEs},
+ {FromIp, FromPort},
+ #peer_state{loc_rts = LRTS} = S) ->
+ ?LOG_INFO("Rx Heartbeat Request from ~p:~p: ~p", [FromIp, FromPort, ReqIEs]),
+ RspIEs = #{recovery_time_stamp => #recovery_time_stamp{time = LRTS}},
+ %% Fake #peer_state to force the right destination and SeqNr
+ {Result, _} = send_pdu({heartbeat_response, RspIEs},
+ S#peer_state{seq_nr = SeqNr,
+ rem_addr = FromIp}),
+ Result.
+
%% vim:set ts=4 sw=4 et:

To view, visit change 37963. To unsubscribe, or for help writing mail filters, visit settings.

Gerrit-MessageType: merged
Gerrit-Project: erlang/osmo-s1gw
Gerrit-Branch: master
Gerrit-Change-Id: Ic4682d49f2e1df08d241500b7b4e75edadaeb91a
Gerrit-Change-Number: 37963
Gerrit-PatchSet: 1
Gerrit-Owner: fixeria <vyanitskiy@sysmocom.de>
Gerrit-Reviewer: Jenkins Builder
Gerrit-Reviewer: fixeria <vyanitskiy@sysmocom.de>
Gerrit-Reviewer: laforge <laforge@osmocom.org>
Gerrit-Reviewer: pespin <pespin@sysmocom.de>