fixeria has submitted this change. ( https://gerrit.osmocom.org/c/erlang/osmo-s1gw/+/39111?usp=email )
Change subject: s1ap_proxy: rework handle_ie/2 into handle_ie/3 ......................................................................
s1ap_proxy: rework handle_ie/2 into handle_ie/3
This patch prepares for a follow-up change adding E-RAB MODIFY REQ/RSP.
Instead of passing the whole record #'ProtocolIE-Field' to handle_ie(), pass the IEI ('id' field) and IE content ('value' field) as separate arguments. This split-up allows to pass the full IEI path to handle_ie() in a follow-up change, and also allows to expand some fields of the IE content right in the function header.
Change-Id: Ic71c8c07739b0e354ca9c9b03c000a366d8c2c43 --- M src/s1ap_proxy.erl 1 file changed, 58 insertions(+), 67 deletions(-)
Approvals: pespin: Looks good to me, but someone else must approve laforge: Looks good to me, but someone else must approve Jenkins Builder: Verified fixeria: Looks good to me, approved
diff --git a/src/s1ap_proxy.erl b/src/s1ap_proxy.erl index 5cacb59..4d78b29 100644 --- a/src/s1ap_proxy.erl +++ b/src/s1ap_proxy.erl @@ -60,7 +60,7 @@ -type s1ap_pdu() :: {initiatingMessage, #'InitiatingMessage'{}} | {successfulOutcome, #'SuccessfulOutcome'{}} | {unsuccessfulOutcome, #'UnsuccessfulOutcome'{}}. --type s1ap_ie() :: #'ProtocolIE-Field'{}. +-type s1ap_ie_id() :: non_neg_integer(). -type s1ap_ie_val() :: tuple().
-type mme_ue_id() :: 0..16#ffffffff. @@ -392,20 +392,23 @@
%% Handle a single IE (Information Element) -type handle_ie_result() :: {ok, s1ap_ie_val()} | {error, term()}. --spec handle_ie(s1ap_ie(), proxy_state()) -> {handle_ie_result(), proxy_state()}. +-spec handle_ie(IEI, C, S) -> Result + when IEI :: s1ap_ie_id(), + C :: s1ap_ie_val(), + S :: proxy_state(), + Result :: {handle_ie_result(), + proxy_state()}.
%% E-RAB SETUP REQUEST related IEs -handle_ie(#'ProtocolIE-Field'{id = ?'id-E-RABToBeSetupListBearerSUReq', - value = Content}, S) -> +handle_ie(?'id-E-RABToBeSetupListBearerSUReq', C, S) -> %% This IE contains a list of BearerSUReq, so patch inner IEs - handle_ies(Content, ?'id-E-RABToBeSetupItemBearerSUReq', S); + handle_ies(C, ?'id-E-RABToBeSetupItemBearerSUReq', S);
-handle_ie(#'ProtocolIE-Field'{id = ?'id-E-RABToBeSetupItemBearerSUReq', - value = C0}, S0) -> +handle_ie(?'id-E-RABToBeSetupItemBearerSUReq', + #'E-RABToBeSetupItemBearerSUReq'{'e-RAB-ID' = ERABId, + 'transportLayerAddress' = TLA_In, + 'gTP-TEID' = << TEID_In:32/big >>} = C0, S0) -> %% start and register an E-RAB FSM - #'E-RABToBeSetupItemBearerSUReq'{'e-RAB-ID' = ERABId, - 'transportLayerAddress' = TLA_In, - 'gTP-TEID' = << TEID_In:32/big >>} = C0, {Pid, S1} = erab_fsm_start_reg(ERABId, S0), case erab_fsm:erab_setup_req(Pid, {TEID_In, TLA_In}) of {ok, {TEID_Out, TLA_Out}} -> @@ -417,17 +420,15 @@ end;
%% E-RAB SETUP RESPONSE related IEs -handle_ie(#'ProtocolIE-Field'{id = ?'id-E-RABSetupListBearerSURes', - value = Content}, S) -> +handle_ie(?'id-E-RABSetupListBearerSURes', C, S) -> %% This IE contains a list of BearerSURes, so patch inner IEs - handle_ies(Content, ?'id-E-RABSetupItemBearerSURes', S); + handle_ies(C, ?'id-E-RABSetupItemBearerSURes', S);
-handle_ie(#'ProtocolIE-Field'{id = ?'id-E-RABSetupItemBearerSURes', - value = C0}, S) -> +handle_ie(?'id-E-RABSetupItemBearerSURes', + #'E-RABSetupItemBearerSURes'{'e-RAB-ID' = ERABId, + 'transportLayerAddress' = TLA_In, + 'gTP-TEID' = << TEID_In:32/big >>} = C0, S) -> %% poke E-RAB FSM - #'E-RABSetupItemBearerSURes'{'e-RAB-ID' = ERABId, - 'transportLayerAddress' = TLA_In, - 'gTP-TEID' = << TEID_In:32/big >>} = C0, case erab_fsm_find(ERABId, S) of {ok, Pid} -> case erab_fsm:erab_setup_rsp(Pid, {TEID_In, TLA_In}) of @@ -444,18 +445,17 @@ end;
%% 9.1.3.5 E-RAB RELEASE COMMAND related IEs -handle_ie(#'ProtocolIE-Field'{id = ?'id-E-RABToBeReleasedList', - value = Content}, S) -> +handle_ie(?'id-E-RABToBeReleasedList', C, S) -> %% This IE contains a list of E-RABItem - handle_ies(Content, ?'id-E-RABItem', S); + handle_ies(C, ?'id-E-RABItem', S);
-handle_ie(#'ProtocolIE-Field'{id = ?'id-E-RABItem', - value = C}, S) -> +handle_ie(?'id-E-RABItem', + #'E-RABItem'{'e-RAB-ID' = ERABId} = C, + #proxy_state{rel_kind = RelKind} = S) -> %% poke E-RAB FSM - #'E-RABItem'{'e-RAB-ID' = ERABId} = C, case erab_fsm_find(ERABId, S) of {ok, Pid} -> - ok = erab_fsm:erab_release(Pid, S#proxy_state.rel_kind), + ok = erab_fsm:erab_release(Pid, RelKind), {{ok, C}, S}; error -> ?LOG_ERROR("E-RAB ~p is not registered", [erab_uid(ERABId, S)]), @@ -463,15 +463,13 @@ end;
%% 9.1.3.6 E-RAB RELEASE RESPONSE related IEs -handle_ie(#'ProtocolIE-Field'{id = ?'id-E-RABReleaseListBearerRelComp', - value = Content}, S) -> +handle_ie(?'id-E-RABReleaseListBearerRelComp', C, S) -> %% This IE contains a list of E-RABReleaseItemBearerRelComp - handle_ies(Content, ?'id-E-RABReleaseItemBearerRelComp', S); + handle_ies(C, ?'id-E-RABReleaseItemBearerRelComp', S);
-handle_ie(#'ProtocolIE-Field'{id = ?'id-E-RABReleaseItemBearerRelComp', - value = C}, S) -> +handle_ie(?'id-E-RABReleaseItemBearerRelComp', + #'E-RABReleaseItemBearerRelComp'{'e-RAB-ID' = ERABId} = C, S) -> %% poke E-RAB FSM - #'E-RABReleaseItemBearerRelComp'{'e-RAB-ID' = ERABId} = C, case erab_fsm_find(ERABId, S) of {ok, Pid} -> ok = erab_fsm:erab_release_rsp(Pid), @@ -482,44 +480,39 @@ end;
%% 9.1.3.7 E-RAB RELEASE INDICATION related IEs -handle_ie(#'ProtocolIE-Field'{id = ?'id-E-RABReleasedList', - value = Content}, S) -> +handle_ie(?'id-E-RABReleasedList', C, S) -> %% This IE contains a list of E-RABItem - handle_ies(Content, ?'id-E-RABItem', S); + handle_ies(C, ?'id-E-RABItem', S);
%% E-RAB MODIFICATION INDICATION related IEs -handle_ie(#'ProtocolIE-Field'{id = ?'id-E-RABToBeModifiedListBearerModInd', - value = Content}, S) -> +handle_ie(?'id-E-RABToBeModifiedListBearerModInd', C, S) -> %% This IE contains a list of BearerModInd, so patch inner IEs - handle_ies(Content, ?'id-E-RABToBeModifiedItemBearerModInd', S); + handle_ies(C, ?'id-E-RABToBeModifiedItemBearerModInd', S);
-handle_ie(#'ProtocolIE-Field'{id = ?'id-E-RABToBeModifiedItemBearerModInd', - value = C}, S) -> +handle_ie(?'id-E-RABToBeModifiedItemBearerModInd', + #'E-RABToBeModifiedItemBearerModInd'{} = C, S) -> %% TODO: find and poke an E-RAB FSM associated with this E-RAB {{ok, C}, S};
-handle_ie(#'ProtocolIE-Field'{id = ?'id-E-RABNotToBeModifiedListBearerModInd', - value = Content}, S) -> +handle_ie(?'id-E-RABNotToBeModifiedListBearerModInd', C, S) -> %% This IE contains a list of BearerModInd, so patch inner IEs - handle_ies(Content, ?'id-E-RABNotToBeModifiedItemBearerModInd', S); + handle_ies(C, ?'id-E-RABNotToBeModifiedItemBearerModInd', S);
-handle_ie(#'ProtocolIE-Field'{id = ?'id-E-RABNotToBeModifiedItemBearerModInd', - value = C}, S) -> +handle_ie(?'id-E-RABNotToBeModifiedItemBearerModInd', + #'E-RABNotToBeModifiedItemBearerModInd'{} = C, S) -> %% TODO: find and poke an E-RAB FSM associated with this E-RAB {{ok, C}, S};
%% INITIAL CONTEXT SETUP REQUEST related IEs -handle_ie(#'ProtocolIE-Field'{id = ?'id-E-RABToBeSetupListCtxtSUReq', - value = Content}, S) -> +handle_ie(?'id-E-RABToBeSetupListCtxtSUReq', C, S) -> %% This IE contains a list of CtxtSUReq, so patch inner IEs - handle_ies(Content, ?'id-E-RABToBeSetupItemCtxtSUReq', S); + handle_ies(C, ?'id-E-RABToBeSetupItemCtxtSUReq', S);
-handle_ie(#'ProtocolIE-Field'{id = ?'id-E-RABToBeSetupItemCtxtSUReq', - value = C0}, S0) -> +handle_ie(?'id-E-RABToBeSetupItemCtxtSUReq', + #'E-RABToBeSetupItemCtxtSUReq'{'e-RAB-ID' = ERABId, + 'transportLayerAddress' = TLA_In, + 'gTP-TEID' = << TEID_In:32/big >>} = C0, S0) -> %% start and register an E-RAB FSM - #'E-RABToBeSetupItemCtxtSUReq'{'e-RAB-ID' = ERABId, - 'transportLayerAddress' = TLA_In, - 'gTP-TEID' = << TEID_In:32/big >>} = C0, {Pid, S1} = erab_fsm_start_reg(ERABId, S0), case erab_fsm:erab_setup_req(Pid, {TEID_In, TLA_In}) of {ok, {TEID_Out, TLA_Out}} -> @@ -531,17 +524,15 @@ end;
%% INITIAL CONTEXT SETUP RESPONSE related IEs -handle_ie(#'ProtocolIE-Field'{id = ?'id-E-RABSetupListCtxtSURes', - value = Content}, S) -> +handle_ie(?'id-E-RABSetupListCtxtSURes', C, S) -> %% This IE contains a list of CtxtSURes, so patch inner IEs - handle_ies(Content, ?'id-E-RABSetupItemCtxtSURes', S); + handle_ies(C, ?'id-E-RABSetupItemCtxtSURes', S);
-handle_ie(#'ProtocolIE-Field'{id = ?'id-E-RABSetupItemCtxtSURes', - value = C0}, S) -> +handle_ie(?'id-E-RABSetupItemCtxtSURes', + #'E-RABSetupItemCtxtSURes'{'e-RAB-ID' = ERABId, + 'transportLayerAddress' = TLA_In, + 'gTP-TEID' = << TEID_In:32/big >>} = C0, S) -> %% poke E-RAB FSM - #'E-RABSetupItemCtxtSURes'{'e-RAB-ID' = ERABId, - 'transportLayerAddress' = TLA_In, - 'gTP-TEID' = << TEID_In:32/big >>} = C0, case erab_fsm_find(ERABId, S) of {ok, Pid} -> case erab_fsm:erab_setup_rsp(Pid, {TEID_In, TLA_In}) of @@ -558,8 +549,8 @@ end;
%% Catch-all variant, which should not be called normally -handle_ie(#'ProtocolIE-Field'{} = IE, S) -> - ?LOG_ERROR("[BUG] Unhandled S1AP IE: ~p", [IE]), +handle_ie(IEI, C, S) -> + ?LOG_ERROR("[BUG] Unhandled S1AP IE: ~p, ~p", [IEI, C]), {{error, unhandled_ie}, S}.
@@ -567,16 +558,16 @@ %% calling function handle_ie/1 for IEs matching the given IEI. %% Additionally look for {MME,eNB}-UE-S1AP-ID IEs and store their values. -type handle_ies_result() :: {ok, list()} | {error, term()}. --spec handle_ies(list(), integer(), proxy_state()) -> {handle_ies_result(), proxy_state()}. +-spec handle_ies(list(), s1ap_ie_id(), proxy_state()) -> {handle_ies_result(), proxy_state()}. handle_ies(IEs, IEI, S) -> handle_ies([], IEs, IEI, S).
handle_ies(Acc, [IE | IEs], IEI, S0) -> case IE of - #'ProtocolIE-Field'{id = IEI} -> - case handle_ie(IE, S0) of - {{ok, C}, S1} -> - NewIE = IE#'ProtocolIE-Field'{value = C}, + #'ProtocolIE-Field'{id = IEI, value = C0} -> + case handle_ie(IEI, C0, S0) of + {{ok, C1}, S1} -> + NewIE = IE#'ProtocolIE-Field'{value = C1}, handle_ies([NewIE | Acc], IEs, IEI, S1); {{error, Reason}, S1} -> {{error, Reason}, S1}