fixeria has uploaded this change for review. ( https://gerrit.osmocom.org/c/erlang/osmo-s1gw/+/37963?usp=email )
Change subject: pfcp_peer: implement the Heartbeat procedure ......................................................................
pfcp_peer: implement the Heartbeat procedure
Change-Id: Ic4682d49f2e1df08d241500b7b4e75edadaeb91a --- M src/pfcp_peer.erl 1 file changed, 32 insertions(+), 3 deletions(-)
git pull ssh://gerrit.osmocom.org:29418/erlang/osmo-s1gw refs/changes/63/37963/1
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: