pespin has submitted this change. ( 
https://gerrit.osmocom.org/c/libosmo-sigtran/+/39640?usp=email )

Change subject: Make sure to NOTIFY current state to peer after ASP UP ACK / 
REG RESP
......................................................................

Make sure to NOTIFY current state to peer after ASP UP ACK / REG RESP

As per  RFC4666 4.3.4.5:
"""
When an ASP moves from ASP-DOWN to ASP-INACTIVE within a particular AS,
a Notify message SHOULD be sent, by the ASP-UP receptor, after sending
the ASP-UP-ACK, in order to inform the ASP of the current AS state."""

It also needs to be done for REG RESP in order to support dynamic
ASPs/ASs, since in that case if dynamic ASP sends to SG an ASP-UP msg,
it contains no RCTX/AS reference, and hence the ASP will only be
assigned to an AS after the REG-REQ is sent, at which point we can send
the AS status to it.

Change-Id: I3dffa2e9c554f03c7c721b757ff33a89961665b5
---
M src/xua_as_fsm.c
M src/xua_as_fsm.h
M src/xua_asp_fsm.c
M src/xua_rkm.c
4 files changed, 129 insertions(+), 27 deletions(-)

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




diff --git a/src/xua_as_fsm.c b/src/xua_as_fsm.c
index 577c7d3..c4a167c 100644
--- a/src/xua_as_fsm.c
+++ b/src/xua_as_fsm.c
@@ -39,6 +39,19 @@
        return msg;
 }

+static void tx_notify(struct osmo_ss7_asp *asp, const struct 
osmo_xlm_prim_notify *npar)
+{
+       const char *type_name, *info_name, *info_str;
+       type_name = get_value_string(m3ua_ntfy_type_names, npar->status_type);
+       info_name = m3ua_ntfy_info_name(npar->status_type, npar->status_info);
+       info_str = npar->info_string ? npar->info_string : "";
+
+       LOGPASP(asp, DLSS7, LOGL_INFO, "Tx NOTIFY Type %s:%s (%s)\n",
+               type_name, info_name, info_str);
+       struct msgb *msg = encode_notify(npar);
+       osmo_ss7_asp_send(asp, msg);
+}
+
 static int as_notify_all_asp(struct osmo_ss7_as *as, struct 
osmo_xlm_prim_notify *npar)
 {
        struct msgb *msg;
@@ -184,6 +197,37 @@
        bool ipa_route_created;
 };

+static void fill_notify_statchg_pars(const struct osmo_fsm_inst *fi, struct 
osmo_xlm_prim_notify *npar)
+{
+       struct xua_as_fsm_priv *xafp = (struct xua_as_fsm_priv *) fi->priv;
+       struct osmo_ss7_as *as = xafp->as;
+       *npar = (struct osmo_xlm_prim_notify){
+               .status_type = M3UA_NOTIFY_T_STATCHG,
+       };
+
+       switch (fi->state) {
+       case XUA_AS_S_INACTIVE:
+               npar->status_info = M3UA_NOTIFY_I_AS_INACT;
+               break;
+       case XUA_AS_S_ACTIVE:
+               npar->status_info = M3UA_NOTIFY_I_AS_ACT;
+               break;
+       case XUA_AS_S_PENDING:
+               npar->status_info = M3UA_NOTIFY_I_AS_PEND;
+               break;
+       case XUA_AS_S_DOWN:
+       default:
+               /* Nothing will be sent anyway... */
+               return;
+       }
+
+       /* Add the routing context, if it is configured */
+       if (as->cfg.routing_key.context) {
+               npar->presence |= NOTIFY_PAR_P_ROUTE_CTX;
+               npar->route_ctx = as->cfg.routing_key.context;
+       }
+}
+
 /* is the given AS one with a single ASP of IPA type? */
 static bool is_single_ipa_asp(struct osmo_ss7_as *as)
 {
@@ -351,21 +395,21 @@
 {
        struct xua_as_fsm_priv *xafp = (struct xua_as_fsm_priv *) fi->priv;
        struct osmo_ss7_as *as = xafp->as;
-       struct osmo_xlm_prim_notify npar = {
-               .status_type = M3UA_NOTIFY_T_STATCHG,
-       };
+       struct osmo_xlm_prim_notify npar;
+
+       fill_notify_statchg_pars(fi, &npar);

        switch (fi->state) {
        case XUA_AS_S_INACTIVE:
-               npar.status_info = M3UA_NOTIFY_I_AS_INACT;
+               /* continue below */
                break;
        case XUA_AS_S_ACTIVE:
                if (is_single_ipa_asp(as))
                        ipa_add_route(fi);
-               npar.status_info = M3UA_NOTIFY_I_AS_ACT;
+               /* continue below */
                break;
        case XUA_AS_S_PENDING:
-               npar.status_info = M3UA_NOTIFY_I_AS_PEND;
+               /* continue below */
                break;
        case XUA_AS_S_DOWN:
                if (is_single_ipa_asp(as))
@@ -384,11 +428,7 @@
                return;
        }

-       /* Add the routing context, if it is configured */
-       if (as->cfg.routing_key.context) {
-               npar.presence |= NOTIFY_PAR_P_ROUTE_CTX;
-               npar.route_ctx = as->cfg.routing_key.context;
-       }
+       fill_notify_statchg_pars(fi, &npar);

        /* TODO: ASP-Id of ASP triggering this state change */

@@ -409,10 +449,13 @@
 static void xua_as_fsm_inactive(struct osmo_fsm_inst *fi, uint32_t event, void 
*data)
 {
        struct xua_as_fsm_priv *xafp = (struct xua_as_fsm_priv *) fi->priv;
-       struct osmo_ss7_asp *asp = data;
+       struct osmo_ss7_asp *asp;
+       struct xua_as_event_asp_inactive_ind_pars *inact_ind_pars;
+       struct osmo_xlm_prim_notify npar;

        switch (event) {
        case XUA_ASPAS_ASP_DOWN_IND:
+               asp = data;
                /* one ASP transitions into ASP-DOWN */
                if (check_any_other_asp_not_down(xafp->as, asp)) {
                        /* ignore, we stay AS_INACTIVE */
@@ -424,7 +467,11 @@
                osmo_fsm_inst_state_chg(fi, XUA_AS_S_ACTIVE, 0, 0);
                break;
        case XUA_ASPAS_ASP_INACTIVE_IND:
-               /* ignore */
+               inact_ind_pars = data;
+               if (inact_ind_pars->asp_requires_notify) {
+                       fill_notify_statchg_pars(fi, &npar);
+                       tx_notify(inact_ind_pars->asp, &npar);
+               }
                break;
        }
 }
@@ -433,14 +480,19 @@
 {
        struct xua_as_fsm_priv *xafp = (struct xua_as_fsm_priv *) fi->priv;
        struct osmo_ss7_asp *asp;
+       struct xua_as_event_asp_inactive_ind_pars *inact_ind_pars;
        struct msgb *msg;
+       struct osmo_xlm_prim_notify npar;

        switch (event) {
        case XUA_ASPAS_ASP_DOWN_IND:
        case XUA_ASPAS_ASP_INACTIVE_IND:
-               asp = data;
-               if (check_any_other_asp_in_active(xafp->as, asp)) {
-                       /* ignore, we stay AS_ACTIVE */
+               inact_ind_pars = data;
+               if (check_any_other_asp_in_active(xafp->as, 
inact_ind_pars->asp)) {
+                       if (event == XUA_ASPAS_ASP_INACTIVE_IND && 
inact_ind_pars->asp_requires_notify) {
+                               fill_notify_statchg_pars(fi, &npar);
+                               tx_notify(inact_ind_pars->asp, &npar);
+                       } /* ASP_DOWN_IND: ignore, nothing to be sent */
                } else {
                        uint32_t recovery_msec = 
xafp->as->cfg.recovery_timeout_msec;
                        osmo_fsm_inst_state_chg(fi, XUA_AS_S_PENDING, 0, 0);
@@ -467,7 +519,9 @@
 static void xua_as_fsm_pending(struct osmo_fsm_inst *fi, uint32_t event, void 
*data)
 {
        struct xua_as_fsm_priv *xafp = (struct xua_as_fsm_priv *) fi->priv;
+       struct xua_as_event_asp_inactive_ind_pars *inact_ind_pars;
        struct msgb *msg;
+       struct osmo_xlm_prim_notify npar;

        switch (event) {
        case XUA_ASPAS_ASP_ACTIVE_IND:
@@ -479,7 +533,11 @@
                        xua_as_transmit_msg(xafp->as, msg);
                break;
        case XUA_ASPAS_ASP_INACTIVE_IND:
-               /* ignore */
+               inact_ind_pars = data;
+               if (inact_ind_pars->asp_requires_notify) {
+                       fill_notify_statchg_pars(fi, &npar);
+                       tx_notify(inact_ind_pars->asp, &npar);
+               }
                break;
        case XUA_ASPAS_ASP_DOWN_IND:
                /* ignore */
diff --git a/src/xua_as_fsm.h b/src/xua_as_fsm.h
index 0e71350..cf897e2 100644
--- a/src/xua_as_fsm.h
+++ b/src/xua_as_fsm.h
@@ -1,6 +1,7 @@
 #pragma once

 struct osmo_ss7_as;
+struct osmo_ss7_asp;

 enum xua_as_state {
        XUA_AS_S_DOWN,
@@ -9,8 +10,17 @@
        XUA_AS_S_PENDING,
 };

+struct xua_as_event_asp_inactive_ind_pars {
+       struct osmo_ss7_asp *asp;
+       /* RFC4666 4.3.4.5: "When an ASP moves from ASP-DOWN to ASP-INACTIVE 
within a
+        * particular AS, a Notify message SHOULD be sent, by the ASP-UP 
receptor,
+        * after sending the ASP-UP-ACK, in order to inform the ASP of the 
current AS
+        * state." */
+       bool asp_requires_notify;
+};
+
 enum xua_as_event {
-       XUA_ASPAS_ASP_INACTIVE_IND,
+       XUA_ASPAS_ASP_INACTIVE_IND, /* param: struct 
xua_as_event_asp_inactive_ind_pars* */
        XUA_ASPAS_ASP_DOWN_IND,
        XUA_ASPAS_ASP_ACTIVE_IND,
        XUA_AS_E_RECOVERY_EXPD,
diff --git a/src/xua_asp_fsm.c b/src/xua_asp_fsm.c
index 12640d6..0e39b0d 100644
--- a/src/xua_asp_fsm.c
+++ b/src/xua_asp_fsm.c
@@ -355,7 +355,7 @@

 /* Helper function to dispatch an ASP->AS event to all AS of which this
  * ASP is a memmber.  Ignores routing contexts for now. */
-static void dispatch_to_all_as(struct osmo_fsm_inst *fi, uint32_t event)
+static void dispatch_to_all_as(struct osmo_fsm_inst *fi, uint32_t event, void 
*data)
 {
        struct xua_asp_fsm_priv *xafp = fi->priv;
        struct osmo_ss7_asp *asp = xafp->asp;
@@ -365,7 +365,7 @@
        llist_for_each_entry(as, &inst->as_list, list) {
                if (!osmo_ss7_as_has_asp(as, asp))
                        continue;
-               osmo_fsm_inst_dispatch(as->fi, event, asp);
+               osmo_fsm_inst_dispatch(as->fi, event, data);
        }
 }

@@ -418,7 +418,9 @@

 static void xua_asp_fsm_down_onenter(struct osmo_fsm_inst *fi, uint32_t 
prev_state)
 {
-       dispatch_to_all_as(fi, XUA_ASPAS_ASP_DOWN_IND);
+       struct xua_asp_fsm_priv *xafp = fi->priv;
+       struct osmo_ss7_asp *asp = xafp->asp;
+       dispatch_to_all_as(fi, XUA_ASPAS_ASP_DOWN_IND, asp);
 }

 static void xua_asp_fsm_down(struct osmo_fsm_inst *fi, uint32_t event, void 
*data)
@@ -478,7 +480,17 @@

 static void xua_asp_fsm_inactive_onenter(struct osmo_fsm_inst *fi, uint32_t 
prev_state)
 {
-       dispatch_to_all_as(fi, XUA_ASPAS_ASP_INACTIVE_IND);
+       struct xua_asp_fsm_priv *xafp = fi->priv;
+       /* RFC4666 4.3.4.5: "When an ASP moves from ASP-DOWN to ASP-INACTIVE 
within a
+        * particular AS, a Notify message SHOULD be sent, by the ASP-UP 
receptor,
+        * after sending the ASP-UP-ACK, in order to inform the ASP of the 
current AS
+        * state."
+        */
+       struct xua_as_event_asp_inactive_ind_pars pars = {
+               .asp = xafp->asp,
+               .asp_requires_notify = (prev_state == XUA_ASP_S_DOWN),
+       };
+       dispatch_to_all_as(fi, XUA_ASPAS_ASP_INACTIVE_IND, &pars);
 }

 static void xua_asp_fsm_inactive(struct osmo_fsm_inst *fi, uint32_t event, 
void *data)
@@ -596,7 +608,9 @@

 static void xua_asp_fsm_active_onenter(struct osmo_fsm_inst *fi, uint32_t 
prev_state)
 {
-       dispatch_to_all_as(fi, XUA_ASPAS_ASP_ACTIVE_IND);
+       struct xua_asp_fsm_priv *xafp = fi->priv;
+       struct osmo_ss7_asp *asp = xafp->asp;
+       dispatch_to_all_as(fi, XUA_ASPAS_ASP_ACTIVE_IND, asp);
 }

 static void xua_asp_fsm_active(struct osmo_fsm_inst *fi, uint32_t event, void 
*data)
@@ -1047,8 +1061,14 @@

 static void ipa_asp_fsm_active_onenter(struct osmo_fsm_inst *fi, uint32_t 
prev_state)
 {
-       dispatch_to_all_as(fi, XUA_ASPAS_ASP_INACTIVE_IND);
-       dispatch_to_all_as(fi, XUA_ASPAS_ASP_ACTIVE_IND);
+       struct ipa_asp_fsm_priv *iafp = fi->priv;
+       struct osmo_ss7_asp *asp = iafp->asp;
+       struct xua_as_event_asp_inactive_ind_pars pars = {
+               .asp = asp,
+               .asp_requires_notify = false,
+       };
+       dispatch_to_all_as(fi, XUA_ASPAS_ASP_INACTIVE_IND, &pars);
+       dispatch_to_all_as(fi, XUA_ASPAS_ASP_ACTIVE_IND, asp);
 }

 /* Server + Client: We're actively transmitting user data */
@@ -1064,7 +1084,12 @@

 static void ipa_asp_fsm_inactive_onenter(struct osmo_fsm_inst *fi, uint32_t 
prev_state)
 {
-       dispatch_to_all_as(fi, XUA_ASPAS_ASP_INACTIVE_IND);
+       struct ipa_asp_fsm_priv *iafp = fi->priv;
+       struct xua_as_event_asp_inactive_ind_pars pars = {
+               .asp = iafp->asp,
+               .asp_requires_notify = false,
+       };
+       dispatch_to_all_as(fi, XUA_ASPAS_ASP_INACTIVE_IND, &pars);
 }

 static void ipa_asp_fsm_inactive(struct osmo_fsm_inst *fi, uint32_t event, 
void *data)
diff --git a/src/xua_rkm.c b/src/xua_rkm.c
index f616a3a..9e77095 100644
--- a/src/xua_rkm.c
+++ b/src/xua_rkm.c
@@ -346,7 +346,16 @@
                if (!as)
                        continue;
                /* Notify AS that it has an INACTIVE ASP */
-               osmo_fsm_inst_dispatch(as->fi, XUA_ASPAS_ASP_INACTIVE_IND, asp);
+               /* RFC4666 4.3.4.5: "When an ASP moves from ASP-DOWN to 
ASP-INACTIVE within a
+               * particular AS, a Notify message SHOULD be sent, by the ASP-UP 
receptor,
+               * after sending the ASP-UP-ACK, in order to inform the ASP of 
the current AS
+               * state."
+               */
+               struct xua_as_event_asp_inactive_ind_pars pars = {
+                       .asp = asp,
+                       .asp_requires_notify = true,
+               };
+               osmo_fsm_inst_dispatch(as->fi, XUA_ASPAS_ASP_INACTIVE_IND, 
&pars);
        }

        return 0;

--
To view, visit https://gerrit.osmocom.org/c/libosmo-sigtran/+/39640?usp=email
To unsubscribe, or for help writing mail filters, visit 
https://gerrit.osmocom.org/settings?usp=email

Gerrit-MessageType: merged
Gerrit-Project: libosmo-sigtran
Gerrit-Branch: master
Gerrit-Change-Id: I3dffa2e9c554f03c7c721b757ff33a89961665b5
Gerrit-Change-Number: 39640
Gerrit-PatchSet: 6
Gerrit-Owner: pespin <pes...@sysmocom.de>
Gerrit-Reviewer: Jenkins Builder
Gerrit-Reviewer: laforge <lafo...@osmocom.org>
Gerrit-Reviewer: osmith <osm...@sysmocom.de>
Gerrit-Reviewer: pespin <pes...@sysmocom.de>

Reply via email to