fixeria has submitted this change. ( 
https://gerrit.osmocom.org/c/erlang/osmo-s1gw/+/42446?usp=email )

Change subject: enb_proxy: split conn_info() into mme_conn_info() and 
proxy_info()
......................................................................

enb_proxy: split conn_info() into mme_conn_info() and proxy_info()

The old conn_info() conflated two distinct concerns: the MME SCTP
connection info stored in enb_registry (aid, saddr, sport) and the
broader operational state used for introspection (handler pid, enb
connection info, etc.).  Mixing them forced enb_registry to hold a
handler pid it has no business knowing about, and required rest_server
to extract that pid just to reach s1ap_proxy for E-RAB listing.

Split into two distinct types:

* mme_conn_info() - pure MME SCTP connection info (aid, saddr, sport),
  stored in the enb_registry and signalled via notify_mme_comm_up/2.
  The `mme_` prefix is dropped from field names as the type name
  provides the context.

* proxy_info() - richer operational snapshot (handler, enb_handle,
  enb_conn_info, mme_conn_info, genb_id_str, mme_info), returned by
  fetch_info/1 for introspection/debugging purposes.

Additionally:

* Add fetch_erab_list/1 to enb_proxy, delegating internally to
  s1ap_proxy:fetch_erab_list/1 via the cached handler pid.  This
  allows the rest_server to obtain a list of E-RAB without having
  to obtain pid of the s1ap_proxy and interact with it.

* Remove separate enb_aid/mme_aid/mme_saddr/mme_sport state fields;
  enb_aid is now read directly from enb_conn_info, and the MME fields
  are grouped in mme_conn_info.

Change-Id: Ia428ceb4762f972211e9b790688dc89fb5b8a274
Related: SYS#7066
---
M src/enb_proxy.erl
M src/enb_registry.erl
M src/rest_server.erl
3 files changed, 66 insertions(+), 68 deletions(-)

Approvals:
  pespin: Looks good to me, but someone else must approve
  fixeria: Looks good to me, approved
  Jenkins Builder: Verified
  laforge: Looks good to me, but someone else must approve




diff --git a/src/enb_proxy.erl b/src/enb_proxy.erl
index 6a7254e..c281b33 100644
--- a/src/enb_proxy.erl
+++ b/src/enb_proxy.erl
@@ -47,6 +47,7 @@
 -export([start_link/2,
          send_data/2,
          fetch_info/1,
+         fetch_erab_list/1,
          shutdown/1]).

 -include_lib("kernel/include/logger.hrl").
@@ -58,18 +59,21 @@
 -include("S1AP-Constants.hrl").


--type conn_info() :: #{handler := pid(),
-                       enb_aid := gen_sctp:assoc_id(),
-                       mme_aid => gen_sctp:assoc_id(),
-                       mme_saddr => inet:ip_address(),
-                       mme_sport => inet:port_number()
-                      }.
+-type mme_conn_info() :: #{aid := gen_sctp:assoc_id(),
+                           saddr := inet:ip_address(),
+                           sport := inet:port_number()
+                          }.

--record(state, {enb_aid :: gen_sctp:assoc_id(),
-                mme_aid :: undefined | gen_sctp:assoc_id(),
-                mme_saddr :: undefined | inet:ip_address(),
-                mme_sport :: undefined | inet:port_number(),
-                enb_conn_info :: sctp_server:conn_info(),
+-type proxy_info() :: #{handler := pid(),
+                        enb_handle := enb_registry:enb_handle(),
+                        enb_conn_info := sctp_server:conn_info(),
+                        mme_conn_info => mme_conn_info(),
+                        mme_info => mme_registry:mme_info(),
+                        genb_id_str => string()
+                       }.
+
+-record(state, {enb_conn_info :: sctp_server:conn_info(),
+                mme_conn_info :: undefined | mme_conn_info(),
                 s1setup_req :: undefined | binary(),
                 tried_mmes :: [mme_registry:mme_name()],
                 enb_tacs :: undefined | [s1ap_utils:tac()],
@@ -81,7 +85,8 @@

 -type state() :: #state{}.

--export_type([conn_info/0]).
+-export_type([mme_conn_info/0,
+              proxy_info/0]).


 %% ------------------------------------------------------------------
@@ -101,11 +106,16 @@
     gen_statem:cast(Pid, {send_data, Data}).


--spec fetch_info(pid()) -> conn_info().
+-spec fetch_info(pid()) -> proxy_info().
 fetch_info(Pid) ->
     gen_statem:call(Pid, ?FUNCTION_NAME).


+-spec fetch_erab_list(pid()) -> [{term(), pid()}].
+fetch_erab_list(Pid) ->
+    gen_statem:call(Pid, ?FUNCTION_NAME).
+
+
 -spec shutdown(pid()) -> ok.
 shutdown(Pid) ->
     gen_statem:stop(Pid).
@@ -119,10 +129,7 @@
     {ok, EnbHandle} = enb_registry:enb_register(),
     {ok, Pid} = s1ap_proxy:start_link(self()),
     {ok, wait_s1setup_req,
-     #state{enb_aid = maps:get(aid, EnbConnInfo),
-            mme_saddr = undefined,
-            mme_sport = undefined,
-            enb_conn_info = EnbConnInfo,
+     #state{enb_conn_info = EnbConnInfo,
             enb_handle = EnbHandle,
             tried_mmes = [],
             handler = Pid}}.
@@ -210,9 +217,7 @@
             enb_registry:notify_mme_connecting(S#state.enb_handle, MmeInfo),
             {next_state, ?FUNCTION_NAME, %% loop transition to enable 
state_timeout
              S#state{sock = Sock,
-                     mme_aid = undefined,
-                     mme_saddr = undefined,
-                     mme_sport = undefined,
+                     mme_conn_info = undefined,
                      tried_mmes = [MmeName | TriedMMEs]},
              [{state_timeout, 2_000, conn_est_timeout}]};
         error ->
@@ -251,14 +256,15 @@
             {ok, {MmeLAddr, MmeLPort}} = inet:sockname(Socket),
             ?LOG_NOTICE("MME ~p: connection (id=~p, ~p:~p) established",
                         [MmeName, Aid, MmeAddr, MmePort]),
-            NewS = S#state{mme_aid = Aid,
-                           mme_saddr = MmeLAddr,
-                           mme_sport = MmeLPort},
+            MmeConnInfo = #{aid => Aid,
+                            saddr => MmeLAddr,
+                            sport => MmeLPort},
             %% send the S1 SETUP REQUEST PDU to the MME
-            sctp_send_from_enb(S#state.s1setup_req, NewS),
+            sctp_send_from_enb(S#state.s1setup_req,
+                               S#state{mme_conn_info = MmeConnInfo}),
             %% surface MME connection details before S1 Setup completes
-            enb_registry:notify_mme_comm_up(S#state.enb_handle, 
conn_info(NewS)),
-            {next_state, wait_s1setup_rsp, NewS};
+            enb_registry:notify_mme_comm_up(S#state.enb_handle, MmeConnInfo),
+            {next_state, wait_s1setup_rsp, S#state{mme_conn_info = 
MmeConnInfo}};
         _ ->
             ?LOG_NOTICE("MME ~p: connection establishment failed: ~p",
                         [MmeName, ConnState]),
@@ -299,7 +305,7 @@
                                            stream = SID,
                                            ssn = SSN,
                                            tsn = TSN}], Data}},
-                 #state{mme_aid = MmeAid} = S) ->
+                 #state{mme_conn_info = #{aid := MmeAid}} = S) ->
     ?LOG_DEBUG("MME connection (id=~p, ~p:~p) -> eNB: ~p",
                [MmeAid, MmeAddr, MmePort,
                 #{tsn => TSN, sid => SID, ssn => SSN,
@@ -382,7 +388,7 @@
                                     stream = SID,
                                     ssn = SSN,
                                     tsn = TSN}], Data}},
-          #state{mme_aid = MmeAid} = S) ->
+          #state{mme_conn_info = #{aid := MmeAid}} = S) ->
     ?LOG_DEBUG("MME connection (id=~p, ~p:~p) -> eNB: ~p",
                [MmeAid, MmeAddr, MmePort,
                 #{tsn => TSN, sid => SID, ssn => SSN,
@@ -401,7 +407,19 @@

 %% Event handler for all states
 handle_event(_State, {call, From}, fetch_info, S) ->
-    {keep_state_and_data, {reply, From, conn_info(S)}};
+    Info = #{handler => S#state.handler,
+             enb_handle => S#state.enb_handle,
+             enb_conn_info => S#state.enb_conn_info,
+             mme_conn_info => S#state.mme_conn_info,
+             %% TODO: mme_info => S#state.mme_info,
+             genb_id_str => S#state.genb_id_str
+            },
+    Reply = maps:filter(fun(_K, V) -> V =/= undefined end, Info),
+    {keep_state_and_data, {reply, From, Reply}};
+
+handle_event(_State, {call, From}, fetch_erab_list, S) ->
+    ERABs = s1ap_proxy:fetch_erab_list(S#state.handler),
+    {keep_state_and_data, {reply, From, ERABs}};

 handle_event(State, {call, From}, EventData, _S) ->
     ?LOG_ERROR("Unexpected call in state ~p: ~p", [State, EventData]),
@@ -445,8 +463,8 @@
 -spec sctp_send_from_enb(binary(), state()) -> ok | {error, term()}.
 sctp_send_from_enb(Data,
                    #state{sock = Sock,
-                          enb_aid = EnbAid,
-                          mme_aid = MmeAid,
+                          enb_conn_info = #{aid := EnbAid},
+                          mme_conn_info = #{aid := MmeAid},
                           handler = Pid}) ->
     case s1ap_proxy:process_pdu(Pid, Data) of
         {forward, FwdData} ->
@@ -462,8 +480,8 @@
 -spec sctp_send_from_mme(binary(), state()) -> ok | {error, term()}.
 sctp_send_from_mme(Data,
                    #state{sock = Sock,
-                          enb_aid = EnbAid,
-                          mme_aid = MmeAid,
+                          enb_conn_info = #{aid := EnbAid},
+                          mme_conn_info = #{aid := MmeAid},
                           handler = Pid}) ->
     case s1ap_proxy:process_pdu(Pid, Data) of
         {forward, FwdData} ->
@@ -475,16 +493,6 @@
     end.


--spec conn_info(state()) -> conn_info().
-conn_info(S) ->
-    Info = #{handler => S#state.handler,
-             enb_aid => S#state.enb_aid,
-             mme_aid => S#state.mme_aid,
-             mme_saddr => S#state.mme_saddr,
-             mme_sport => S#state.mme_sport},
-    maps:filter(fun(_K, V) -> V =/= undefined end, Info).
-
-
 -spec gtpu_kpi_enb_register(state()) -> ok.
 gtpu_kpi_enb_register(#state{genb_id_str = GlobalENBId,
                              enb_conn_info = EnbConnInfo}) ->
@@ -566,9 +574,9 @@


 -spec close_conn(state()) -> ok | {error, term()}.
-close_conn(#state{mme_aid = undefined}) -> ok;
+close_conn(#state{mme_conn_info = undefined}) -> ok;

-close_conn(#state{sock = Sock, mme_aid = MmeAid}) ->
+close_conn(#state{sock = Sock, mme_conn_info = #{aid := MmeAid}}) ->
     sctp_common:shutdown({Sock, MmeAid}).


diff --git a/src/enb_registry.erl b/src/enb_registry.erl
index 2bf6e47..a65ecbf 100644
--- a/src/enb_registry.erl
+++ b/src/enb_registry.erl
@@ -66,7 +66,7 @@

 -type enb_prop() :: {state, atom()}
                   | {enb_conn_info, sctp_server:conn_info()}
-                  | {mme_conn_info, undefined | enb_proxy:conn_info()}
+                  | {mme_conn_info, undefined | enb_proxy:mme_conn_info()}
                   | {mme_info, mme_registry:mme_info()}
                   | {genb_id, s1ap_utils:genb_id()}.
 -type enb_proplist() :: [enb_prop()].
@@ -86,7 +86,7 @@
                       genb_id => s1ap_utils:genb_id(),             %% 
Global-eNB-ID
                       genb_id_str => string(),                     %% 
Global-eNB-ID string
                       enb_conn_info => sctp_server:conn_info(),    %% eNB -> 
S1GW connection info
-                      mme_conn_info => enb_proxy:conn_info(),      %% S1GW -> 
MME connection info
+                      mme_conn_info => enb_proxy:mme_conn_info(),  %% S1GW -> 
MME connection info
                       mme_info => mme_registry:mme_info()          %% selected 
MME configuration
                      }.

@@ -139,7 +139,7 @@


 %% MME SCTP comm_up; connection details (aid, saddr, sport) are now known
--spec notify_mme_comm_up(enb_handle(), enb_proxy:conn_info()) -> ok.
+-spec notify_mme_comm_up(enb_handle(), enb_proxy:mme_conn_info()) -> ok.
 notify_mme_comm_up(Handle, ConnInfo) ->
     enb_update(Handle, [{mme_conn_info, ConnInfo}]).

@@ -381,7 +381,7 @@
     fun(_, Item) -> enb_filter_by_sub_field({enb_conn_info, aid, Aid}, Item) 
end;

 enb_filter({mme_sctp_aid, Aid}) ->
-    fun(_, Item) -> enb_filter_by_sub_field({mme_conn_info, mme_aid, Aid}, 
Item) end;
+    fun(_, Item) -> enb_filter_by_sub_field({mme_conn_info, aid, Aid}, Item) 
end;

 enb_filter({enb_addr_port, {Addr, Port}}) ->
     fun(_, Item) -> enb_filter_by_sub_field({enb_conn_info, addr, Addr}, Item) 
andalso
diff --git a/src/rest_server.erl b/src/rest_server.erl
index 5913b3b..315c66e 100644
--- a/src/rest_server.erl
+++ b/src/rest_server.erl
@@ -427,11 +427,12 @@

 -spec enb_item(enb_registry:enb_info()) -> map().
 enb_item(EnbInfo) ->
+    ERABs = enb_proxy:fetch_erab_list(maps:get(pid, EnbInfo)),
     M0 = #{handle => maps:get(handle, EnbInfo),
            pid => pid_to_list(maps:get(pid, EnbInfo)),
            state => maps:get(state, EnbInfo),
            uptime => maps:get(uptime, EnbInfo),
-           erab_count => 0},
+           erab_count => length(ERABs)},
     M1 = enb_item_add_enb_info(M0, EnbInfo),
     M2 = enb_item_add_enb_conn_info(M1, EnbInfo),
     M3 = enb_item_add_mme_conn_info(M2, EnbInfo),
@@ -463,18 +464,10 @@

 -spec enb_item_add_mme_conn_info(map(), enb_registry:enb_info()) -> map().
 enb_item_add_mme_conn_info(M0, #{mme_conn_info := ConnInfo}) ->
-    Pid = maps:get(handler, ConnInfo),
-    ERABs = s1ap_proxy:fetch_erab_list(Pid),
-    M1 = M0#{erab_count => length(ERABs)},
-    %% mme_aid/mme_saddr/mme_sport are only present once the MME SCTP
-    %% connection is fully established (comm_up); handle them together.
-    case maps:find(mme_aid, ConnInfo) of
-        {ok, Aid} ->
-            M1#{mme_sctp_aid => Aid,
-                mme_saddr => inet:ntoa(maps:get(mme_saddr, ConnInfo)),
-                mme_sport => maps:get(mme_sport, ConnInfo)};
-        error -> M1
-    end;
+    M0#{mme_saddr => inet:ntoa(maps:get(saddr, ConnInfo)),
+        mme_sport => maps:get(sport, ConnInfo),
+        mme_sctp_aid => maps:get(aid, ConnInfo)
+       };

 enb_item_add_mme_conn_info(M0, _) -> M0.

@@ -547,12 +540,9 @@


 -spec fetch_erab_list(enb_registry:enb_info()) -> [map()].
-fetch_erab_list(#{mme_conn_info := ConnInfo}) ->
-    Pid = maps:get(handler, ConnInfo), %% s1ap_proxy process pid
-    ERABs = s1ap_proxy:fetch_erab_list(Pid),
-    lists:map(fun erab_list_item/1, ERABs);
-
-fetch_erab_list(_) -> [].
+fetch_erab_list(#{pid := EnbPid}) ->
+    ERABs = enb_proxy:fetch_erab_list(EnbPid),
+    lists:map(fun erab_list_item/1, ERABs).

 
 -spec erab_list_item({term(), pid()}) -> map().

--
To view, visit https://gerrit.osmocom.org/c/erlang/osmo-s1gw/+/42446?usp=email
To unsubscribe, or for help writing mail filters, visit 
https://gerrit.osmocom.org/settings?usp=email

Gerrit-MessageType: merged
Gerrit-Project: erlang/osmo-s1gw
Gerrit-Branch: master
Gerrit-Change-Id: Ia428ceb4762f972211e9b790688dc89fb5b8a274
Gerrit-Change-Number: 42446
Gerrit-PatchSet: 4
Gerrit-Owner: fixeria <[email protected]>
Gerrit-Reviewer: Jenkins Builder
Gerrit-Reviewer: fixeria <[email protected]>
Gerrit-Reviewer: laforge <[email protected]>
Gerrit-Reviewer: pespin <[email protected]>

Reply via email to