aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--src/sccp_internal.h23
-rw-r--r--src/sccp_scoc.c110
-rw-r--r--src/sccp_user.c4
-rw-r--r--src/sccp_vty.c40
4 files changed, 56 insertions, 121 deletions
diff --git a/src/sccp_internal.h b/src/sccp_internal.h
index 3027ae6..0367fe1 100644
--- a/src/sccp_internal.h
+++ b/src/sccp_internal.h
@@ -4,6 +4,7 @@
#include <osmocom/core/prim.h>
#include <osmocom/core/linuxlist.h>
#include <osmocom/core/linuxrbtree.h>
+#include <osmocom/core/tdef.h>
#include <osmocom/sigtran/sccp_sap.h>
#include <osmocom/sigtran/osmo_ss7.h>
#include <osmocom/sigtran/protocol/mtp.h>
@@ -12,7 +13,8 @@
/* Appendix C.4 of Q.714 */
enum osmo_sccp_timer {
- OSMO_SCCP_TIMER_CONN_EST,
+ /* 0 kept unused on purpose since it's handled specially by osmo_fsm */
+ OSMO_SCCP_TIMER_CONN_EST = 1,
OSMO_SCCP_TIMER_IAS,
OSMO_SCCP_TIMER_IAR,
OSMO_SCCP_TIMER_REL,
@@ -22,24 +24,15 @@ enum osmo_sccp_timer {
OSMO_SCCP_TIMER_RESET,
OSMO_SCCP_TIMER_REASSEMBLY,
/* This must remain the last item: */
- OSMO_SCCP_TIMERS_COUNT
+ OSMO_SCCP_TIMERS_LEN
};
-struct osmo_sccp_timer_val {
- uint32_t s;
- uint32_t us;
-};
-
-extern const struct osmo_sccp_timer_val osmo_sccp_timer_defaults[];
+extern const struct osmo_tdef osmo_sccp_timer_defaults[OSMO_SCCP_TIMERS_LEN];
extern const struct value_string osmo_sccp_timer_names[];
static inline const char *osmo_sccp_timer_name(enum osmo_sccp_timer val)
{ return get_value_string(osmo_sccp_timer_names, val); }
-extern const struct value_string osmo_sccp_timer_descriptions[];
-static inline const char *osmo_sccp_timer_description(enum osmo_sccp_timer val)
-{ return get_value_string(osmo_sccp_timer_descriptions, val); }
-
/* an instance of the SCCP stack */
struct osmo_sccp_instance {
/* entry in global list of ss7 instances */
@@ -57,7 +50,7 @@ struct osmo_sccp_instance {
struct osmo_ss7_user ss7_user;
- struct osmo_sccp_timer_val timers[OSMO_SCCP_TIMERS_COUNT];
+ struct osmo_tdef *tdefs;
uint32_t max_optional_data;
};
@@ -129,10 +122,6 @@ extern struct osmo_fsm sccp_scoc_fsm;
void sccp_scoc_show_connections(struct vty *vty, struct osmo_sccp_instance *inst);
-const struct osmo_sccp_timer_val *osmo_sccp_timer_get(const struct osmo_sccp_instance *inst,
- enum osmo_sccp_timer timer,
- bool default_if_unset);
-
void osmo_sccp_vty_write_cs7_node(struct vty *vty, const char *indent, struct osmo_sccp_instance *inst);
/* Local Broadcast (LBCS) */
diff --git a/src/sccp_scoc.c b/src/sccp_scoc.c
index f6caeac..e273d17 100644
--- a/src/sccp_scoc.c
+++ b/src/sccp_scoc.c
@@ -234,6 +234,31 @@ static const struct osmo_prim_event_map scu_scoc_event_map[] = {
* Timer Handling
***********************************************************************/
+/* Mostly pasted from Appendix C.4 of ITU-T Q.714 (05/2001) -- some of their descriptions are quite
+ * unintelligible out of context, for which we have our own description here. */
+const struct osmo_tdef osmo_sccp_timer_defaults[OSMO_SCCP_TIMERS_LEN] = {
+ { .T = OSMO_SCCP_TIMER_CONN_EST, .default_val = 1*60, .unit = OSMO_TDEF_S,
+ .desc = "Waiting for connection confirm message, 1 to 2 minutes" },
+ { .T = OSMO_SCCP_TIMER_IAS, .default_val = 7*60, .unit = OSMO_TDEF_S,
+ .desc = "Send keep-alive: on an idle connection, delay before sending an Idle Timer message, 5 to 10 minutes" }, /* RFC 3868 Ch. 8. */
+ { .T = OSMO_SCCP_TIMER_IAR, .default_val = 15*60, .unit = OSMO_TDEF_S,
+ .desc = "Receive keep-alive: on an idle connection, delay until considering a connection as stale, 11 to 21 minutes" }, /* RFC 3868 Ch. 8. */
+ { .T = OSMO_SCCP_TIMER_REL, .default_val = 10, .unit = OSMO_TDEF_S,
+ .desc = "Waiting for release complete message, 10 to 20 seconds" },
+ { .T = OSMO_SCCP_TIMER_REPEAT_REL, .default_val = 10, .unit = OSMO_TDEF_S,
+ .desc = "Waiting for release complete message; or to repeat sending released message after the initial expiry, 10 to 20 seconds" },
+ { .T = OSMO_SCCP_TIMER_INT, .default_val = 1*60, .unit = OSMO_TDEF_S,
+ .desc = "Waiting for release complete message; or to release connection resources, freeze the LRN and "
+ "alert a maintenance function after the initial expiry, extending to 1 minute" },
+ { .T = OSMO_SCCP_TIMER_GUARD, .default_val = 23*60, .unit = OSMO_TDEF_S,
+ .desc = "Waiting to resume normal procedure for temporary connection sections during the restart procedure, 23 to 25 minutes" },
+ { .T = OSMO_SCCP_TIMER_RESET, .default_val = 10, .unit = OSMO_TDEF_S,
+ .desc = "Waiting to release temporary connection section or alert maintenance function after reset request message is sent, 10 to 20 seconds" },
+ { .T = OSMO_SCCP_TIMER_REASSEMBLY, .default_val = 10, .unit = OSMO_TDEF_S,
+ .desc = "Waiting to receive all the segments of the remaining segments, single segmented message after receiving the first segment, 10 to 20 seconds" },
+ {}
+};
+
/* Appendix C.4 of ITU-T Q.714 */
const struct value_string osmo_sccp_timer_names[] = {
{ OSMO_SCCP_TIMER_CONN_EST, "conn_est" },
@@ -248,93 +273,16 @@ const struct value_string osmo_sccp_timer_names[] = {
{}
};
-/* Mostly pasted from Appendix C.4 of ITU-T Q.714 (05/2001) -- some of their descriptions are quite
- * unintelligible out of context, for which we have our own description here. */
-const struct value_string osmo_sccp_timer_descriptions[] = {
- { OSMO_SCCP_TIMER_CONN_EST,
- "Waiting for connection confirm message, 1 to 2 minutes" },
- { OSMO_SCCP_TIMER_IAS,
- "Send keep-alive: on an idle connection, delay before sending an Idle Timer message,"
- " 5 to 10 minutes" },
- { OSMO_SCCP_TIMER_IAR,
- "Receive keep-alive: on an idle connection, delay until considering a connection as stale,"
- " 11 to 21 minutes" },
- { OSMO_SCCP_TIMER_REL,
- "Waiting for release complete message, 10 to 20 seconds" },
- { OSMO_SCCP_TIMER_REPEAT_REL,
- "Waiting for release complete message; or to repeat sending released message after the initial"
- " expiry, 10 to 20 seconds" },
- { OSMO_SCCP_TIMER_INT,
- "Waiting for release complete message; or to release connection resources, freeze the LRN and"
- " alert a maintenance function after the initial expiry, extending to 1 minute" },
- { OSMO_SCCP_TIMER_GUARD,
- "Waiting to resume normal procedure for temporary connection sections during the restart"
- " procedure, 23 to 25 minutes" },
- { OSMO_SCCP_TIMER_RESET,
- "Waiting to release temporary connection section or alert maintenance function after reset"
- " request message is sent, 10 to 20 seconds" },
- { OSMO_SCCP_TIMER_REASSEMBLY,
- "Waiting to receive all the segments of the remaining segments, single segmented message after"
- " receiving the first segment, 10 to 20 seconds" },
- {}
-};
-
-/* Appendix C.4 of ITU-T Q.714 */
-const struct osmo_sccp_timer_val osmo_sccp_timer_defaults[] = {
- [OSMO_SCCP_TIMER_CONN_EST] = { .s = 1 * 60, },
- [OSMO_SCCP_TIMER_IAS] = { .s = 7 * 60, }, /* RFC 3868 Ch. 8. */
- [OSMO_SCCP_TIMER_IAR] = { .s = 15 * 60, }, /* RFC 3868 Ch. 8. */
- [OSMO_SCCP_TIMER_REL] = { .s = 10, },
- [OSMO_SCCP_TIMER_REPEAT_REL] = { .s = 10, },
- [OSMO_SCCP_TIMER_INT] = { .s = 1 * 60, },
- [OSMO_SCCP_TIMER_GUARD] = { .s = 23 * 60, },
- [OSMO_SCCP_TIMER_RESET] = { .s = 10, },
- [OSMO_SCCP_TIMER_REASSEMBLY] = { .s = 10, },
-};
-
-osmo_static_assert(ARRAY_SIZE(osmo_sccp_timer_defaults) == OSMO_SCCP_TIMERS_COUNT,
+osmo_static_assert(ARRAY_SIZE(osmo_sccp_timer_defaults) == (OSMO_SCCP_TIMERS_LEN) &&
+ ARRAY_SIZE(osmo_sccp_timer_names) == (OSMO_SCCP_TIMERS_LEN),
assert_osmo_sccp_timers_count);
-/* Look up an SCCP timer value as configured in the osmo_ss7_instance.
- * If no user defined value is set, return the global default from osmo_sccp_timer_defaults instead.
- * However, if default_if_unset is passed false, return NULL in case there is no user defined setting, or
- * in case it is identical to the global default. */
-const struct osmo_sccp_timer_val *osmo_sccp_timer_get(const struct osmo_sccp_instance *inst,
- enum osmo_sccp_timer timer,
- bool default_if_unset)
-{
- const struct osmo_sccp_timer_val *val;
- const struct osmo_sccp_timer_val *def;
-
- OSMO_ASSERT(timer >= 0
- && timer < ARRAY_SIZE(inst->timers)
- && timer < ARRAY_SIZE(osmo_sccp_timer_defaults));
-
- val = &inst->timers[timer];
- def = &osmo_sccp_timer_defaults[timer];
-
- /* Assert that all timer definitions have a sane global default */
- OSMO_ASSERT(def->s || def->us);
-
- if (val->s || val->us) {
- if (!default_if_unset && val->s == def->s && val->us == def->us)
- return NULL;
- return val;
- }
-
- if (!default_if_unset)
- return NULL;
-
- /* If unset, use the global default. */
- return def;
-}
-
static void sccp_timer_schedule(const struct sccp_connection *conn,
struct osmo_timer_list *timer,
enum osmo_sccp_timer timer_name)
{
- const struct osmo_sccp_timer_val *val = osmo_sccp_timer_get(conn->inst, timer_name, true);
- osmo_timer_schedule(timer, val->s, val->us);
+ const unsigned long val_sec = osmo_tdef_get(conn->inst->tdefs, timer_name, OSMO_TDEF_S, -1);
+ osmo_timer_schedule(timer, val_sec, 0);
}
/* T(ias) has expired, send a COIT message to the peer */
diff --git a/src/sccp_user.c b/src/sccp_user.c
index fb14e75..382e1fe 100644
--- a/src/sccp_user.c
+++ b/src/sccp_user.c
@@ -238,6 +238,10 @@ osmo_sccp_instance_create(struct osmo_ss7_instance *ss7, void *priv)
inst->ss7_user.priv = inst;
inst->max_optional_data = SCCP_MAX_OPTIONAL_DATA;
+ inst->tdefs = talloc_memdup(inst, osmo_sccp_timer_defaults,
+ sizeof(osmo_sccp_timer_defaults));
+ osmo_tdefs_reset(inst->tdefs);
+
rc = sccp_scmg_init(inst);
if (rc < 0) {
talloc_free(inst);
diff --git a/src/sccp_vty.c b/src/sccp_vty.c
index dda3ff0..4bd1e4d 100644
--- a/src/sccp_vty.c
+++ b/src/sccp_vty.c
@@ -150,9 +150,8 @@ DEFUN_ATTR(sccp_timer, sccp_timer_cmd,
{
struct osmo_ss7_instance *ss7 = vty->index;
enum osmo_sccp_timer timer = get_string_value(osmo_sccp_timer_names, argv[0]);
- struct osmo_sccp_timer_val set_val = { .s = atoi(argv[1]) };
- if (timer < 0 || timer >= OSMO_SCCP_TIMERS_COUNT) {
+ if (timer <= 0 || timer >= OSMO_SCCP_TIMERS_LEN) {
vty_out(vty, "%% Invalid timer: %s%s", argv[0], VTY_NEWLINE);
return CMD_WARNING;
}
@@ -163,7 +162,8 @@ DEFUN_ATTR(sccp_timer, sccp_timer_cmd,
return CMD_WARNING;
}
- ss7->sccp->timers[timer] = set_val;
+ OSMO_ASSERT(ss7->sccp->tdefs);
+ osmo_tdef_set(ss7->sccp->tdefs, timer, atoi(argv[1]), OSMO_TDEF_S);
return CMD_SUCCESS;
}
@@ -197,14 +197,6 @@ DEFUN_ATTR(sccp_max_optional_data, sccp_max_optional_data_cmd,
return CMD_SUCCESS;
}
-static const char *osmo_sccp_timer_val_name(const struct osmo_sccp_timer_val *val)
-{
- static char buf[16];
-
- snprintf(buf, sizeof(buf), "%u", val->s);
- return buf;
-}
-
static void gen_sccp_timer_cmd_strs(struct cmd_element *cmd)
{
int i;
@@ -219,19 +211,19 @@ static void gen_sccp_timer_cmd_strs(struct cmd_element *cmd)
"Configure SCCP timer values, see ITU-T Q.714\n");
for (i = 0; osmo_sccp_timer_names[i].str; i++) {
- const struct osmo_sccp_timer_val *def;
+ const struct osmo_tdef *def;
enum osmo_sccp_timer timer;
timer = osmo_sccp_timer_names[i].value;
- def = &osmo_sccp_timer_defaults[timer];
- OSMO_ASSERT(timer >= 0 && timer < OSMO_SCCP_TIMERS_COUNT);
+ def = osmo_tdef_get_entry((struct osmo_tdef *)&osmo_sccp_timer_defaults, timer);
+ OSMO_ASSERT(def);
osmo_talloc_asprintf(tall_vty_ctx, cmd_str, "%s%s",
i ? "|" : "",
- osmo_sccp_timer_name(timer));
- osmo_talloc_asprintf(tall_vty_ctx, doc_str, "%s (default: %s)\n",
- osmo_sccp_timer_description(timer),
- osmo_sccp_timer_val_name(def));
+ osmo_sccp_timer_names[i].str);
+ osmo_talloc_asprintf(tall_vty_ctx, doc_str, "%s (default: %lu)\n",
+ def->desc,
+ def->default_val);
}
osmo_talloc_asprintf(tall_vty_ctx, cmd_str, ") <1-999999>");
@@ -247,12 +239,14 @@ static void write_sccp_timers(struct vty *vty, const char *indent,
{
int i;
- for (i = 0; i < ARRAY_SIZE(inst->timers); i++) {
- const struct osmo_sccp_timer_val *val = osmo_sccp_timer_get(inst, i, default_if_unset);
- if (!val)
+ for (i = 0; osmo_sccp_timer_names[i].str; i++) {
+ const struct osmo_tdef *tdef = osmo_tdef_get_entry(inst->tdefs, osmo_sccp_timer_names[i].value);
+ if (!tdef)
+ continue;
+ if (!default_if_unset && tdef->val == tdef->default_val)
continue;
- vty_out(vty, "%ssccp-timer %s %s%s", indent, osmo_sccp_timer_name(i),
- osmo_sccp_timer_val_name(val), VTY_NEWLINE);
+ vty_out(vty, "%ssccp-timer %s %lu%s", indent, osmo_sccp_timer_names[i].str,
+ tdef->val, VTY_NEWLINE);
}
}