fixeria submitted this change.

View Change

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
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(-)

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}

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

Gerrit-MessageType: merged
Gerrit-Project: erlang/osmo-s1gw
Gerrit-Branch: master
Gerrit-Change-Id: Ic71c8c07739b0e354ca9c9b03c000a366d8c2c43
Gerrit-Change-Number: 39111
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>