This is merely a historical archive of years 2008-2021, before the migration to mailman3.
A maintained and still updated list archive can be found at https://lists.osmocom.org/hyperkitty/list/gerrit-log@lists.osmocom.org/.
laforge gerrit-no-reply at lists.osmocom.orglaforge has uploaded this change for review. ( https://gerrit.osmocom.org/c/libosmo-sccp/+/22835 ) Change subject: xua_snm: Implement handling of DUPU messages ...................................................................... xua_snm: Implement handling of DUPU messages A DUPU message in SUA and M3UA indicates the unavailability of a (MTP-level) user, i.e. the entire SCCP, ISUP, ... is not available. If we receive a DUPU (destination user part unavailable) message in ASP role, then we must * distribute it to any other ASPs for which we operate in SG mode * pass it as MTP-STATUS.ind to SCCP, which can then generates N-PCSTATE.ind to the SCCP User Change-Id: I1559ed0f761a8495b222df48c6bd43798e220471 --- M include/osmocom/sigtran/protocol/mtp.h M src/m3ua.c M src/osmo_ss7.c M src/sccp_internal.h M src/sccp_scmg.c M src/sua.c M src/xua_internal.h M src/xua_snm.c 8 files changed, 222 insertions(+), 1 deletion(-) git pull ssh://gerrit.osmocom.org:29418/libosmo-sccp refs/changes/35/22835/1 diff --git a/include/osmocom/sigtran/protocol/mtp.h b/include/osmocom/sigtran/protocol/mtp.h index 8b990c0..2f0c7ac 100644 --- a/include/osmocom/sigtran/protocol/mtp.h +++ b/include/osmocom/sigtran/protocol/mtp.h @@ -22,3 +22,18 @@ }; extern const struct value_string mtp_si_vals[]; + + +/* Chapter 15.17.5 of Q.705 */ +enum mtp_unavail_cause { + MTP_UNAVAIL_C_UNKNOWN = 0x0, + MTP_UNAVAIL_C_UNEQUIP_REM_USER = 0x1, + MTP_UNAVAIL_C_INACC_REM_USER = 0x2, + /* reserved */ +}; + +extern const struct value_string mtp_unavail_cause_vals[]; + +static inline const char *mtp_unavail_cause_str(enum mtp_unavail_cause cs) { + return get_value_string(mtp_unavail_cause_vals, cs); +} diff --git a/src/m3ua.c b/src/m3ua.c index 6639c28..77326e0 100644 --- a/src/m3ua.c +++ b/src/m3ua.c @@ -812,8 +812,29 @@ } #endif +/* 3.4.5 Destination User Part Unavailable (DUPU) */ +static struct xua_msg *m3ua_encode_dupu(const uint32_t *rctx, unsigned int num_rctx, + uint32_t dpc, uint16_t user, uint16_t cause, + const char *info_string) +{ + struct xua_msg *xua = xua_msg_alloc(); + uint32_t user_cause = (user << 16) | cause; -/* TODO: 3.4.5 Destination User Part Unavailable (DUPU) */ + xua->hdr = XUA_HDR(M3UA_MSGC_SNM, M3UA_SNM_DUNA); + xua->hdr.version = M3UA_VERSION; + if (rctx) + xua_msg_add_data(xua, M3UA_IEI_ROUTE_CTX, num_rctx * sizeof(*rctx), (const uint8_t *)rctx); + + xua_msg_add_u32(xua, M3UA_IEI_AFFECTED_PC, dpc); + xua_msg_add_u32(xua, M3UA_IEI_USER_CAUSE, user_cause); + + if (info_string) { + xua_msg_add_data(xua, M3UA_IEI_INFO_STRING, + strlen(info_string)+1, + (const uint8_t *) info_string); + } + return xua; +} /*! Transmit SSNM DUNA/DAVA message indicating [un]availability of certain point code[s] * \param[in] asp ASP through which to transmit message. Must be ACTIVE. @@ -837,6 +858,21 @@ m3ua_tx_xua_asp(asp, xua); } +/*! Transmit SSNM DUPU message indicating user unavailability. + * \param[in] asp ASP through which to transmit message. Must be ACTIVE. + * \param[in] rctx array of Routing Contexts in network byte order. + * \param[in] num_rctx number of rctx + * \param[in] dpc affected point code + * \param[in] user the user (SI) that is unavailable + * \param[in] cause the cause of the user unavailability + * \param[in] info_string optional information string (can be NULL). */ +void m3ua_tx_dupu(struct osmo_ss7_asp *asp, const uint32_t *rctx, unsigned int num_rctx, + uint32_t dpc, uint16_t user, uint16_t cause, const char *info_str) +{ + struct xua_msg *xua = m3ua_encode_dupu(rctx, num_rctx, dpc, user, cause, info_str); + m3ua_tx_xua_asp(asp, xua); +} + /* received SNM message on ASP side */ static int m3ua_rx_snm_asp(struct osmo_ss7_asp *asp, struct xua_msg *xua) { @@ -857,6 +893,8 @@ xua_snm_rx_dava(asp, as, xua); break; case M3UA_SNM_DUPU: + xua_snm_rx_dupu(asp, as, xua); + break; case M3UA_SNM_SCON: case M3UA_SNM_DRST: LOGPASP(asp, DLM3UA, LOGL_NOTICE, "Received unsupported M3UA SNM message type %u\n", diff --git a/src/osmo_ss7.c b/src/osmo_ss7.c index e549708..a801cc9 100644 --- a/src/osmo_ss7.c +++ b/src/osmo_ss7.c @@ -59,6 +59,13 @@ static int32_t next_rctx = 1; static int32_t next_l_rk_id = 1; +const struct value_string mtp_unavail_cause_vals[] = { + { MTP_UNAVAIL_C_UNKNOWN, "unknown" }, + { MTP_UNAVAIL_C_UNEQUIP_REM_USER, "unequipped-remote-user" }, + { MTP_UNAVAIL_C_INACC_REM_USER, "inaccessible-remote-user" }, + { 0, NULL } +}; + struct value_string osmo_ss7_as_traffic_mode_vals[] = { { OSMO_SS7_AS_TMOD_BCAST, "broadcast" }, { OSMO_SS7_AS_TMOD_LOADSHARE, "loadshare" }, diff --git a/src/sccp_internal.h b/src/sccp_internal.h index a95b07d..23b3ef3 100644 --- a/src/sccp_internal.h +++ b/src/sccp_internal.h @@ -4,6 +4,7 @@ #include <osmocom/core/prim.h> #include <osmocom/sigtran/sccp_sap.h> #include <osmocom/sigtran/osmo_ss7.h> +#include <osmocom/sigtran/protocol/mtp.h> #define SCCP_STR "Signalling Connection Control Part\n" @@ -141,4 +142,5 @@ void sccp_scmg_rx_ssn_prohibited(struct osmo_sccp_instance *inst, uint32_t dpc, uint32_t ssn, uint32_t smi); void sccp_scmg_rx_mtp_pause(struct osmo_sccp_instance *inst, uint32_t dpc); void sccp_scmg_rx_mtp_resume(struct osmo_sccp_instance *inst, uint32_t dpc); +void sccp_scmg_rx_mtp_status(struct osmo_sccp_instance *inst, uint32_t dpc, enum mtp_unavail_cause cause); int sccp_scmg_init(struct osmo_sccp_instance *inst); diff --git a/src/sccp_scmg.c b/src/sccp_scmg.c index 49e09ca..a5d6226 100644 --- a/src/sccp_scmg.c +++ b/src/sccp_scmg.c @@ -122,6 +122,39 @@ * [this would require us to track SSNs at each PC, which we don't] */ } +void sccp_scmg_rx_mtp_status(struct osmo_sccp_instance *inst, uint32_t dpc, enum mtp_unavail_cause cause) +{ + struct osmo_scu_pcstate_param pcstate; + /* 1) Informs the translation function to update the translation tables. */ + /* 2) In the case where the SCCP has received an MTP-STATUS indication primitive relating to + Mark the status of the SCCP and each SSN for the relevant destination to "prohibited" + and initiates a subsystem status test with SSN = 1. If the cause in the MTP-STATUS + indication primitive indicates "unequipped user", then no subsystem status test is + initiated. */ + /* 3) Discontinues all subsystem status tests (including SSN = 1) if an MTP-STATUS + indication primitive is received with a cause of "unequipped SCCP". The SCCP + discontinues all subsystem status tests, except for SSN = 1, if an MTP-STATUS + indication primitive is received with a cause of either "unknown" or "inaccessible" */ + switch (cause) { + case MTP_UNAVAIL_C_UNKNOWN: + case MTP_UNAVAIL_C_UNEQUIP_REM_USER: + case MTP_UNAVAIL_C_INACC_REM_USER: + break; + } + + /* 4) local broadcast of "user-out-of-service" for each SSN at that dest + * [this would require us to track SSNs at each PC, which we don't] */ + + /* 6) local broadcast of "remote SCCP unavailable" */ + pcstate = (struct osmo_scu_pcstate_param) { + .affected_pc = dpc, + .restricted_importance_level = 0, + .sp_status = OSMO_SCCP_SP_S_ACCESSIBLE, + .remote_sccp_status = OSMO_SCCP_REM_SCCP_S_UNAVAILABLE_UNKNOWN, + }; + sccp_lbcs_local_bcast_pcstate(inst, &pcstate); +} + const struct value_string sccp_scmg_msgt_names[] = { { SCCP_SCMG_MSGT_SSA, "SSA (Subsystem Allowed)" }, { SCCP_SCMG_MSGT_SSP, "SSP (Subsystem Prohibited)" }, diff --git a/src/sua.c b/src/sua.c index c9e880f..2ff5a9a 100644 --- a/src/sua.c +++ b/src/sua.c @@ -823,6 +823,28 @@ } #endif +/* 3.4.5 Destination User Part Unavailable (DUPU) */ +static struct xua_msg *sua_encode_dupu(const uint32_t *rctx, unsigned int num_rctx, + uint32_t dpc, uint16_t user, uint16_t cause, + const char *info_string) +{ + struct xua_msg *xua = xua_msg_alloc(); + uint32_t user_cause = (user << 16) | cause; + + xua->hdr = XUA_HDR(SUA_MSGC_SNM, SUA_SNM_DUNA); + xua->hdr.version = SUA_VERSION; + if (rctx) + xua_msg_add_data(xua, SUA_IEI_ROUTE_CTX, num_rctx * sizeof(*rctx), (const uint8_t *)rctx); + + xua_msg_add_u32(xua, SUA_IEI_AFFECTED_PC, dpc); + xua_msg_add_u32(xua, SUA_IEI_USER_CAUSE, user_cause); + + if (info_string) { + xua_msg_add_data(xua, SUA_IEI_INFO_STRING, strlen(info_string)+1, + (const uint8_t *) info_string); + } + return xua; +} /*! Transmit SSNM DUNA/DAVA message indicating [un]availability of certain point code[s] * \param[in] asp ASP through whihc to transmit message. Must be ACTIVE. @@ -848,6 +870,21 @@ sua_tx_xua_asp(asp, xua); } +/*! Transmit SSNM DUPU message indicating user unavailability. + * \param[in] asp ASP through which to transmit message. Must be ACTIVE. + * \param[in] rctx array of Routing Contexts in network byte order. + * \param[in] num_rctx number of rctx + * \param[in] dpc affected point code + * \param[in] user the user (SI) that is unavailable + * \param[in] cause the cause of the user unavailability + * \param[in] info_string optional information string (can be NULL). */ +void sua_tx_dupu(struct osmo_ss7_asp *asp, const uint32_t *rctx, unsigned int num_rctx, + uint32_t dpc, uint16_t user, uint16_t cause, const char *info_str) +{ + struct xua_msg *xua = sua_encode_dupu(rctx, num_rctx, dpc, user, cause, info_str); + sua_tx_xua_asp(asp, xua); +} + /* received SNM message on ASP side */ static int sua_rx_snm_asp(struct osmo_ss7_asp *asp, struct xua_msg *xua) { @@ -867,6 +904,8 @@ xua_snm_rx_dava(asp, as, xua); break; case SUA_SNM_DUPU: + xua_snm_rx_dupu(asp, as, xua); + break; case SUA_SNM_SCON: case SUA_SNM_DRST: LOGPASP(asp, DLSUA, LOGL_NOTICE, "Received unsupported SUA SNM message type %u\n", diff --git a/src/xua_internal.h b/src/xua_internal.h index e76fddf..4c6bb29 100644 --- a/src/xua_internal.h +++ b/src/xua_internal.h @@ -21,6 +21,8 @@ void sua_tx_snm_available(struct osmo_ss7_asp *asp, const uint32_t *rctx, unsigned int num_rctx, const uint32_t *aff_pc, unsigned int num_aff_pc, const uint32_t *aff_ssn, const uint32_t *smi, const char *info_string, bool available); +void sua_tx_dupu(struct osmo_ss7_asp *asp, const uint32_t *rctx, unsigned int num_rctx, + uint32_t dpc, uint16_t user, uint16_t cause, const char *info_str); struct osmo_mtp_prim *m3ua_to_xfer_ind(struct xua_msg *xua); int m3ua_hmdc_rx_from_l2(struct osmo_ss7_instance *inst, struct xua_msg *xua); @@ -28,9 +30,12 @@ void m3ua_tx_snm_available(struct osmo_ss7_asp *asp, const uint32_t *rctx, unsigned int num_rctx, const uint32_t *aff_pc, unsigned int num_aff_pc, const char *info_string, bool available); +void m3ua_tx_dupu(struct osmo_ss7_asp *asp, const uint32_t *rctx, unsigned int num_rctx, + uint32_t dpc, uint16_t user, uint16_t cause, const char *info_str); void xua_snm_rx_daud(struct osmo_ss7_asp *asp, struct xua_msg *xua); void xua_snm_rx_duna(struct osmo_ss7_asp *asp, struct osmo_ss7_as *as, struct xua_msg *xua); void xua_snm_rx_dava(struct osmo_ss7_asp *asp, struct osmo_ss7_as *as, struct xua_msg *xua); +void xua_snm_rx_dupu(struct osmo_ss7_asp *asp, struct osmo_ss7_as *as, struct xua_msg *xua); int m3ua_rx_msg(struct osmo_ss7_asp *asp, struct msgb *msg); struct msgb *m3ua_msgb_alloc(const char *name); diff --git a/src/xua_snm.c b/src/xua_snm.c index 2a383c7..0c14964 100644 --- a/src/xua_snm.c +++ b/src/xua_snm.c @@ -29,6 +29,7 @@ #include <osmocom/sigtran/osmo_ss7.h> #include <osmocom/sigtran/protocol/m3ua.h> #include <osmocom/sigtran/protocol/sua.h> +#include <osmocom/sigtran/protocol/mtp.h> #include "xua_internal.h" #include "sccp_internal.h" @@ -99,6 +100,22 @@ } } +static void xua_tx_upu(struct osmo_ss7_asp *asp, const uint32_t *rctx, unsigned int num_rctx, + uint32_t dpc, uint16_t user, uint16_t cause, const char *info_str) +{ + switch (asp->cfg.proto) { + case OSMO_SS7_ASP_PROT_M3UA: + m3ua_tx_dupu(asp, rctx, num_rctx, dpc, user, cause, info_str); + break; + case OSMO_SS7_ASP_PROT_SUA: + sua_tx_dupu(asp, rctx, num_rctx, dpc, user, cause, info_str); + break; + default: + break; + } +} + + /* generate MTP-PAUSE / MTP-RESUME towards local SCCP users */ static void xua_snm_pc_available_to_sccp(struct osmo_sccp_instance *sccp, const uint32_t *aff_pc, unsigned int num_aff_pc, @@ -208,6 +225,37 @@ } } +static void xua_snm_upu(struct osmo_ss7_as *as, uint32_t dpc, uint16_t user, uint16_t cause, + const char *info_str) +{ + struct osmo_ss7_instance *s7i = as->inst; + struct osmo_ss7_asp *asp; + uint32_t rctx[32]; + unsigned int num_rctx; + + /* Translate to MTP-STATUS.ind towards SCCP (will create N-PCSTATE.ind to SCU) */ + if (s7i->sccp && user == MTP_SI_SCCP) + sccp_scmg_rx_mtp_status(s7i->sccp, dpc, cause); + + /* inform remote ASPs via DUPU */ + llist_for_each_entry(asp, &s7i->asp_list, list) { + /* SSNM is only permitted for ASPs in ACTIVE state */ + if (!osmo_ss7_asp_active(asp)) + continue; + + /* only send DAVA/DUNA if we locally are the SG and the remote is ASP */ + if (asp->cfg.role != OSMO_SS7_ASP_ROLE_SG) + continue; + + num_rctx = get_all_rctx_for_asp(rctx, ARRAY_SIZE(rctx), asp, as); + /* this can happen if the given ASP is only in the AS that reports the change, + * which shall be excluded */ + if (num_rctx == 0) + continue; + + xua_tx_upu(asp, rctx, num_rctx, dpc, user, cause, info_str); + } +} /* receive DAUD from ASP; pc is 'affected PC' IE with mask in network byte order! */ void xua_snm_rx_daud(struct osmo_ss7_asp *asp, struct xua_msg *xua) @@ -323,3 +371,37 @@ ie_aff_pc->len / sizeof(uint32_t), info_str, true); } } + +/* an incoming SUA/M3UA DUPU was received from a remote SG */ +void xua_snm_rx_dupu(struct osmo_ss7_asp *asp, struct osmo_ss7_as *as, struct xua_msg *xua) +{ + uint32_t aff_pc = xua_msg_get_u32(xua, SUA_IEI_AFFECTED_PC); + const char *info_str = xua_msg_get_str(xua, SUA_IEI_INFO_STRING); + /* TODO: should our processing depend on the RCTX included? I somehow don't think so */ + //struct xua_msg_part *ie_rctx = xua_msg_find_tag(xua, SUA_IEI_ROUTE_CTX); + int log_ss = osmo_ss7_asp_get_log_subsys(asp); + uint32_t cause_user; + uint16_t cause, user; + + if (asp->cfg.role != OSMO_SS7_ASP_ROLE_ASP) + return; + + switch (asp->cfg.proto) { + case OSMO_SS7_ASP_PROT_M3UA: + cause_user = xua_msg_get_u32(xua, M3UA_IEI_USER_CAUSE); + break; + case OSMO_SS7_ASP_PROT_SUA: + cause_user = xua_msg_get_u32(xua, SUA_IEI_USER_CAUSE); + break; + default: + return; + } + + cause = cause_user >> 16; + user = cause_user & 0xffff; + LOGPASP(asp, log_ss, LOGL_NOTICE, "Rx DUPU(%s) for %s User %s, cause %u\n", + info_str ? info_str : "", osmo_ss7_pointcode_print(asp->inst, aff_pc), + get_value_string(mtp_si_vals, user), cause); + + xua_snm_upu(as, aff_pc, user, cause, info_str); +} -- To view, visit https://gerrit.osmocom.org/c/libosmo-sccp/+/22835 To unsubscribe, or for help writing mail filters, visit https://gerrit.osmocom.org/settings Gerrit-Project: libosmo-sccp Gerrit-Branch: master Gerrit-Change-Id: I1559ed0f761a8495b222df48c6bd43798e220471 Gerrit-Change-Number: 22835 Gerrit-PatchSet: 1 Gerrit-Owner: laforge <laforge at osmocom.org> Gerrit-MessageType: newchange -------------- next part -------------- An HTML attachment was scrubbed... URL: <http://lists.osmocom.org/pipermail/gerrit-log/attachments/20210210/9e74e610/attachment.htm>