pespin has uploaded this change for review. ( https://gerrit.osmocom.org/c/libosmo-gprs/+/32310 )
Change subject: sndcp: Allocate snme->comp.{data,proto} during snme alloc
......................................................................
sndcp: Allocate snme->comp.{data,proto} during snme alloc
This way we guarantee the llist object is always available even before
an XID.req is received (which may not be the case in NET mode).
Change-Id: Ib9540cc62a61ad7cb26ae90ec1500f1a022bada5
---
M src/sndcp/sndcp.c
1 file changed, 17 insertions(+), 2 deletions(-)
git pull ssh://gerrit.osmocom.org:29418/libosmo-gprs refs/changes/10/32310/1
diff --git a/src/sndcp/sndcp.c b/src/sndcp/sndcp.c
index ff38b1c..6041ecd 100644
--- a/src/sndcp/sndcp.c
+++ b/src/sndcp/sndcp.c
@@ -53,6 +53,9 @@
return NULL;
snme->tlli = tlli;
+ snme->comp.proto = gprs_sndcp_comp_alloc(snme);
+ snme->comp.data = gprs_sndcp_comp_alloc(snme);
+
llist_add(&snme->list, &g_sndcp_ctx->snme_list);
return snme;
@@ -698,8 +701,8 @@
* get rid of possible leftovers from a previous session */
gprs_sndcp_comp_free(sne->snme->comp.proto);
gprs_sndcp_comp_free(sne->snme->comp.data);
- sne->snme->comp.proto = gprs_sndcp_comp_alloc(sne);
- sne->snme->comp.data = gprs_sndcp_comp_alloc(sne);
+ sne->snme->comp.proto = gprs_sndcp_comp_alloc(sne->snme);
+ sne->snme->comp.data = gprs_sndcp_comp_alloc(sne->snme);
/* Generate compression parameter bytestream */
sne->l3xid_req_len = gprs_sndcp_sne_gen_sndcp_xid(sne, l3params, sizeof(l3params), sndcp_prim);
--
To view, visit https://gerrit.osmocom.org/c/libosmo-gprs/+/32310
To unsubscribe, or for help writing mail filters, visit https://gerrit.osmocom.org/settings
Gerrit-Project: libosmo-gprs
Gerrit-Branch: master
Gerrit-Change-Id: Ib9540cc62a61ad7cb26ae90ec1500f1a022bada5
Gerrit-Change-Number: 32310
Gerrit-PatchSet: 1
Gerrit-Owner: pespin <pespin(a)sysmocom.de>
Gerrit-MessageType: newchange
neels has submitted this change. ( https://gerrit.osmocom.org/c/osmo-bsc/+/32151 )
Change subject: SCCP N-PCSTATE: trigger MSC status on PC availability
......................................................................
SCCP N-PCSTATE: trigger MSC status on PC availability
Related: SYS#6319
Related: Ia1aea4e33230d6a685b72ea5ba20dd9c7d265d44 osmo-ttcn3-hacks
Related: Ib4a5330df30a73e744c316898817b2fa3271d75e osmo-ttcn3-hacks
Change-Id: I3a0869598b8395601a16d78dbc46eec400c0ea84
---
M include/osmocom/bsc/bssmap_reset.h
M src/osmo-bsc/bssmap_reset.c
M src/osmo-bsc/osmo_bsc_sigtran.c
3 files changed, 123 insertions(+), 1 deletion(-)
Approvals:
laforge: Looks good to me, but someone else must approve
neels: Looks good to me, approved
msuraev: Looks good to me, but someone else must approve
Jenkins Builder: Verified
diff --git a/include/osmocom/bsc/bssmap_reset.h b/include/osmocom/bsc/bssmap_reset.h
index fcd850b..c0de13c 100644
--- a/include/osmocom/bsc/bssmap_reset.h
+++ b/include/osmocom/bsc/bssmap_reset.h
@@ -28,4 +28,5 @@
struct bssmap_reset *bssmap_reset_alloc(void *ctx, const char *label, const struct bssmap_reset_cfg *cfg);
bool bssmap_reset_is_conn_ready(const struct bssmap_reset *bssmap_reset);
void bssmap_reset_resend_reset(struct bssmap_reset *bssmap_reset);
+void bssmap_reset_set_disconnected(struct bssmap_reset *bssmap_reset);
void bssmap_reset_term_and_free(struct bssmap_reset *bssmap_reset);
diff --git a/src/osmo-bsc/bssmap_reset.c b/src/osmo-bsc/bssmap_reset.c
index fa6684d..ac304a5 100644
--- a/src/osmo-bsc/bssmap_reset.c
+++ b/src/osmo-bsc/bssmap_reset.c
@@ -251,6 +251,12 @@
osmo_fsm_inst_state_chg_ms(bssmap_reset->fi, BSSMAP_RESET_ST_DISC, 1, 0);
}
+void bssmap_reset_set_disconnected(struct bssmap_reset *bssmap_reset)
+{
+ /* Go to disconnected state, with the normal RESET timeout to re-send RESET. */
+ bssmap_reset_fsm_state_chg(bssmap_reset->fi, BSSMAP_RESET_ST_DISC);
+}
+
static __attribute__((constructor)) void bssmap_reset_fsm_init(void)
{
OSMO_ASSERT(osmo_fsm_register(&bssmap_reset_fsm) == 0);
diff --git a/src/osmo-bsc/osmo_bsc_sigtran.c b/src/osmo-bsc/osmo_bsc_sigtran.c
index 8837330..f4c8f81 100644
--- a/src/osmo-bsc/osmo_bsc_sigtran.c
+++ b/src/osmo-bsc/osmo_bsc_sigtran.c
@@ -36,6 +36,7 @@
#include <osmocom/bsc/gsm_data.h>
#include <osmocom/bsc/bts.h>
#include <osmocom/bsc/paging.h>
+#include <osmocom/bsc/bssmap_reset.h>
#include <osmocom/mgcp_client/mgcp_common.h>
/* A pointer to a list with all involved MSCs
@@ -92,7 +93,7 @@
&msc->a.msc_addr, msg);
}
-/* Find an MSC by its sigtran point code */
+/* Find an MSC by its remote SCCP address */
static struct bsc_msc_data *get_msc_by_addr(const struct osmo_sccp_addr *msc_addr)
{
struct osmo_ss7_instance *ss7;
@@ -107,6 +108,21 @@
return NULL;
}
+/* Find an MSC by its remote sigtran point code on a given cs7 instance. */
+static struct bsc_msc_data *get_msc_by_pc(struct osmo_ss7_instance *cs7, uint32_t pc)
+{
+ struct bsc_msc_data *msc;
+ llist_for_each_entry(msc, msc_list, entry) {
+ if (msc->a.cs7_instance != cs7->cfg.id)
+ continue;
+ if ((msc->a.msc_addr.presence & OSMO_SCCP_ADDR_T_PC) == 0)
+ continue;
+ if (msc->a.msc_addr.pc == pc)
+ return msc;
+ }
+ return NULL;
+}
+
/* Received data from MSC, use the connection id which MSC it is */
static int handle_data_from_msc(struct gsm_subscriber_connection *conn, struct msgb *msg)
{
@@ -188,6 +204,89 @@
return rc;
}
+static void handle_pcstate_ind(struct osmo_ss7_instance *cs7, const struct osmo_scu_pcstate_param *pcst)
+{
+ struct bsc_msc_data *msc;
+ bool connected;
+ bool disconnected;
+
+ LOGP(DMSC, LOGL_DEBUG, "N-PCSTATE ind: affected_pc=%u sp_status=%d remote_sccp_status=%d\n",
+ pcst->affected_pc, pcst->sp_status, pcst->remote_sccp_status);
+
+ /* If we don't care about that point-code, ignore PCSTATE. */
+ msc = get_msc_by_pc(cs7, pcst->affected_pc);
+ if (!msc)
+ return;
+
+ /* See if this marks the point code to have become available, or to have been lost.
+ *
+ * I want to detect two events:
+ * - connection event (both indicators say PC is reachable).
+ * - disconnection event (at least one indicator says the PC is not reachable).
+ *
+ * There are two separate incoming indicators with various possible values -- the incoming events can be:
+ *
+ * - neither connection nor disconnection indicated -- just indicating congestion
+ * connected == false, disconnected == false --> do nothing.
+ * - both incoming values indicate that we are connected
+ * --> trigger connected
+ * - both indicate we are disconnected
+ * --> trigger disconnected
+ * - one value indicates 'connected', the other indicates 'disconnected'
+ * --> trigger disconnected
+ *
+ * Congestion could imply that we're connected, but it does not indicate that a PC's reachability changed, so no need to
+ * trigger on that.
+ */
+ connected = false;
+ disconnected = false;
+
+ switch (pcst->sp_status) {
+ case OSMO_SCCP_SP_S_ACCESSIBLE:
+ connected = true;
+ break;
+ case OSMO_SCCP_SP_S_INACCESSIBLE:
+ disconnected = true;
+ break;
+ default:
+ case OSMO_SCCP_SP_S_CONGESTED:
+ /* Neither connecting nor disconnecting */
+ break;
+ }
+
+ switch (pcst->remote_sccp_status) {
+ case OSMO_SCCP_REM_SCCP_S_AVAILABLE:
+ if (!disconnected)
+ connected = true;
+ break;
+ case OSMO_SCCP_REM_SCCP_S_UNAVAILABLE_UNKNOWN:
+ case OSMO_SCCP_REM_SCCP_S_UNEQUIPPED:
+ case OSMO_SCCP_REM_SCCP_S_INACCESSIBLE:
+ disconnected = true;
+ connected = false;
+ break;
+ default:
+ case OSMO_SCCP_REM_SCCP_S_CONGESTED:
+ /* Neither connecting nor disconnecting */
+ break;
+ }
+
+ if (disconnected && a_reset_conn_ready(msc)) {
+ LOGP(DMSC, LOGL_NOTICE,
+ "(msc%d) now unreachable: N-PCSTATE ind: pc=%u sp_status=%d remote_sccp_status=%d\n",
+ msc->nr, pcst->affected_pc, pcst->sp_status, pcst->remote_sccp_status);
+ /* A previously usable MSC has disconnected. Kick the BSSMAP back to DISC state. */
+ bssmap_reset_set_disconnected(msc->a.bssmap_reset);
+ } else if (connected && !a_reset_conn_ready(msc)) {
+ LOGP(DMSC, LOGL_NOTICE,
+ "(msc%d) now available: N-PCSTATE ind: pc=%u sp_status=%d remote_sccp_status=%d\n",
+ msc->nr, pcst->affected_pc, pcst->sp_status, pcst->remote_sccp_status);
+ /* A previously unusable MSC has become reachable. Trigger immediate BSSMAP RESET -- we would resend a
+ * RESET either way, but we might as well do it now to speed up connecting. */
+ bssmap_reset_resend_reset(msc->a.bssmap_reset);
+ }
+}
+
/* Callback function, called by the SCCP stack when data arrives */
static int sccp_sap_up(struct osmo_prim_hdr *oph, void *_scu)
{
@@ -255,6 +354,10 @@
}
break;
+ case OSMO_PRIM(OSMO_SCU_PRIM_N_PCSTATE, PRIM_OP_INDICATION):
+ handle_pcstate_ind(osmo_sccp_get_ss7(sccp), &scu_prim->u.pcstate);
+ break;
+
default:
LOGP(DMSC, LOGL_ERROR, "Unhandled SIGTRAN operation %s on primitive %u\n",
get_value_string(osmo_prim_op_names, oph->operation), oph->primitive);
--
To view, visit https://gerrit.osmocom.org/c/osmo-bsc/+/32151
To unsubscribe, or for help writing mail filters, visit https://gerrit.osmocom.org/settings
Gerrit-Project: osmo-bsc
Gerrit-Branch: master
Gerrit-Change-Id: I3a0869598b8395601a16d78dbc46eec400c0ea84
Gerrit-Change-Number: 32151
Gerrit-PatchSet: 5
Gerrit-Owner: neels <nhofmeyr(a)sysmocom.de>
Gerrit-Reviewer: Jenkins Builder
Gerrit-Reviewer: laforge <laforge(a)osmocom.org>
Gerrit-Reviewer: msuraev <msuraev(a)sysmocom.de>
Gerrit-Reviewer: neels <nhofmeyr(a)sysmocom.de>
Gerrit-CC: pespin <pespin(a)sysmocom.de>
Gerrit-MessageType: merged