diff options
-rw-r--r-- | src/sccp_internal.h | 23 | ||||
-rw-r--r-- | src/sccp_scoc.c | 110 | ||||
-rw-r--r-- | src/sccp_user.c | 4 | ||||
-rw-r--r-- | src/sccp_vty.c | 40 |
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); } } |