pespin has uploaded this change for review. ( https://gerrit.osmocom.org/c/libosmo-sigtran/+/38719?usp=email )
Change subject: sigtran: Add API osmo_ss7_as_select_asp() ......................................................................
sigtran: Add API osmo_ss7_as_select_asp()
This API is required by osmo-bsc, since when in SCCPLite configuration, it needs to access the IPA conn of the AS towards the MSC in order to inject MGCP and CTRL protocols over the IPA multiplex.
This API may need to be revisited (i.e. deprecated and a new one created) once we want to fully support loadshare, where message contents such as OPC,DPC,SLS need to be taken into account internally in libosmo-sigtran. That new version may well be kept private though, since the API here presented is good enough for osmo-bsc IPA multiplex injection. This is anyway kind of chicken-and-egg problem, because we want to have an API osmo-bsc can use in first place before moving the whole osmo_ss7_as struct as private so that we can modify it to implement proper AS loadsharing.
Related: SYS#6602 Change-Id: I8b866b45ac4a24238c55171d25e11b9625e8f50c --- M TODO-RELEASE M include/osmocom/sigtran/osmo_ss7.h M src/osmo_ss7_as.c M src/xua_as_fsm.c 4 files changed, 92 insertions(+), 39 deletions(-)
git pull ssh://gerrit.osmocom.org:29418/libosmo-sigtran refs/changes/19/38719/1
diff --git a/TODO-RELEASE b/TODO-RELEASE index 261567c..08978d4 100644 --- a/TODO-RELEASE +++ b/TODO-RELEASE @@ -13,4 +13,4 @@ libosmo-sigtran Make private osmo_ss7_route libosmo-sigtran add API osmo_ss7_instance_get_id(), osmo_ss7_instance_get_name(), osmo_ss7_instance_get_pc_fmt(), osmo_ss7_instance_get_primary_pc(), osmo_ss7_get_sccp() libosmo-sigtran add API osmo_ss7_instances_llist_entry() -libosmo-sigtran add API osmo_ss7_as_get_asp_protocol() +libosmo-sigtran add API osmo_ss7_as_get_asp_protocol(), osmo_ss7_as_select_asp() diff --git a/include/osmocom/sigtran/osmo_ss7.h b/include/osmocom/sigtran/osmo_ss7.h index 83956d8..361e715 100644 --- a/include/osmocom/sigtran/osmo_ss7.h +++ b/include/osmocom/sigtran/osmo_ss7.h @@ -274,6 +274,7 @@ void osmo_ss7_as_destroy(struct osmo_ss7_as *as); bool osmo_ss7_as_has_asp(const struct osmo_ss7_as *as, const struct osmo_ss7_asp *asp); +struct osmo_ss7_asp *osmo_ss7_as_select_asp(struct osmo_ss7_as *as); bool osmo_ss7_as_down(const struct osmo_ss7_as *as); bool osmo_ss7_as_active(const struct osmo_ss7_as *as); bool osmo_ss7_as_tmode_compatible_xua(struct osmo_ss7_as *as, uint32_t m3ua_tmt); diff --git a/src/osmo_ss7_as.c b/src/osmo_ss7_as.c index 5af7098..d4510fc 100644 --- a/src/osmo_ss7_as.c +++ b/src/osmo_ss7_as.c @@ -222,3 +222,89 @@ return true; return as->fi->state == XUA_AS_S_DOWN; } + +static struct osmo_ss7_asp *ss7_as_select_asp_override(struct osmo_ss7_as *as) +{ + struct osmo_ss7_asp *asp; + unsigned int i; + + /* FIXME: proper selection of the ASP based on the SLS! */ + for (i = 0; i < ARRAY_SIZE(as->cfg.asps); i++) { + asp = as->cfg.asps[i]; + if (asp && osmo_ss7_asp_active(asp)) + break; + } + return asp; +} + +static struct osmo_ss7_asp *ss7_as_select_asp_roundrobin(struct osmo_ss7_as *as) +{ + struct osmo_ss7_asp *asp; + unsigned int i; + unsigned int first_idx; + + first_idx = (as->cfg.last_asp_idx_sent + 1) % ARRAY_SIZE(as->cfg.asps); + i = first_idx; + do { + asp = as->cfg.asps[i]; + if (asp && osmo_ss7_asp_active(asp)) + break; + i = (i + 1) % ARRAY_SIZE(as->cfg.asps); + } while (i != first_idx); + as->cfg.last_asp_idx_sent = i; + + return asp; +} + +static struct osmo_ss7_asp *ss7_as_select_asp_broadcast(struct osmo_ss7_as *as) +{ + struct osmo_ss7_asp *asp; + struct osmo_ss7_asp *asp_found = NULL; + unsigned int cnt = 0; + + for (unsigned int i = 0; i < ARRAY_SIZE(as->cfg.asps); i++) { + asp = as->cfg.asps[i]; + if (!asp || !osmo_ss7_asp_active(asp)) + continue; + asp_found = asp; + cnt++; + if (cnt > 1) + break; /* Early return above: */ + } + return cnt == 1 ? asp_found : NULL; +} + +/*! Select an AS to transmit a message, according to AS configuration and ASP availability. + * \param[in] as Application Server. + * \returns asp to send the message to, NULL if no possible asp found + * + * This function returns NULL too if multiple ASPs would be selected, ie. AS is + * configured in broadcast mode and more than one ASP is configured. + */ +struct osmo_ss7_asp *osmo_ss7_as_select_asp(struct osmo_ss7_as *as) +{ + struct osmo_ss7_asp *asp = NULL; + + switch (as->cfg.mode) { + case OSMO_SS7_AS_TMOD_OVERRIDE: + asp = ss7_as_select_asp_override(as); + break; + case OSMO_SS7_AS_TMOD_LOADSHARE: + /* TODO: actually use the SLS value to ensure same SLS goes + * through same ASP. Not strictly required by M3UA RFC, but + * would fit the overall principle. */ + case OSMO_SS7_AS_TMOD_ROUNDROBIN: + asp = ss7_as_select_asp_roundrobin(as); + break; + case OSMO_SS7_AS_TMOD_BCAST: + return ss7_as_select_asp_broadcast(as); + case _NUM_OSMO_SS7_ASP_TMOD: + OSMO_ASSERT(false); + } + + if (!asp) { + LOGPFSM(as->fi, "No selectable ASP in AS\n"); + return NULL; + } + return asp; +} diff --git a/src/xua_as_fsm.c b/src/xua_as_fsm.c index dff0d06..29d31a9 100644 --- a/src/xua_as_fsm.c +++ b/src/xua_as_fsm.c @@ -97,39 +97,6 @@ return -1; }
-static struct osmo_ss7_asp *xua_as_select_asp_override(struct osmo_ss7_as *as) -{ - struct osmo_ss7_asp *asp; - unsigned int i; - - /* FIXME: proper selection of the ASP based on the SLS! */ - for (i = 0; i < ARRAY_SIZE(as->cfg.asps); i++) { - asp = as->cfg.asps[i]; - if (asp && osmo_ss7_asp_active(asp)) - break; - } - return asp; -} - -static struct osmo_ss7_asp *xua_as_select_asp_roundrobin(struct osmo_ss7_as *as) -{ - struct osmo_ss7_asp *asp; - unsigned int i; - unsigned int first_idx; - - first_idx = (as->cfg.last_asp_idx_sent + 1) % ARRAY_SIZE(as->cfg.asps); - i = first_idx; - do { - asp = as->cfg.asps[i]; - if (asp && osmo_ss7_asp_active(asp)) - break; - i = (i + 1) % ARRAY_SIZE(as->cfg.asps); - } while (i != first_idx); - as->cfg.last_asp_idx_sent = i; - - return asp; -} - int xua_as_transmit_msg_broadcast(struct osmo_ss7_as *as, struct msgb *msg) { struct osmo_ss7_asp *asp; @@ -157,13 +124,12 @@
switch (as->cfg.mode) { case OSMO_SS7_AS_TMOD_OVERRIDE: - asp = xua_as_select_asp_override(as); - break; case OSMO_SS7_AS_TMOD_LOADSHARE: - /* TODO: actually use the SLS value to ensure same SLS goes through same ASP. Not - * strictly required by M3UA RFC, but would fit the overall principle. */ + /* TODO: OSMO_SS7_AS_TMOD_LOADSHARE: actually use the SLS value + * to ensure same SLS goes through same ASP. Not strictly + * required by M3UA RFC, but would fit the overall principle. */ case OSMO_SS7_AS_TMOD_ROUNDROBIN: - asp = xua_as_select_asp_roundrobin(as); + asp = osmo_ss7_as_select_asp(as); break; case OSMO_SS7_AS_TMOD_BCAST: return xua_as_transmit_msg_broadcast(as, msg);