aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--.gitignore2
-rw-r--r--Makefile.am2
-rw-r--r--configure.ac1
-rw-r--r--include/osmocom/sigtran/osmo_ss7.h2
-rw-r--r--src/osmo_ss7.c7
-rw-r--r--stp/Makefile.am11
-rw-r--r--stp/internal.h18
-rw-r--r--stp/osmo_ss7_vty.c (renamed from src/osmo_ss7_vty.c)324
-rw-r--r--stp/stp_main.c101
9 files changed, 410 insertions, 58 deletions
diff --git a/.gitignore b/.gitignore
index 83f1333..c38bac1 100644
--- a/.gitignore
+++ b/.gitignore
@@ -62,6 +62,8 @@ tests/testsuite.log
examples/m3ua_example
+stp/osmo-stp
+
*.pc
config.*
diff --git a/Makefile.am b/Makefile.am
index dd73ec2..ededdac 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -1,7 +1,7 @@
AUTOMAKE_OPTIONS = foreign dist-bzip2 1.6
AM_CPPFLAGS = $(all_includes) -I$(top_srcdir)/include
-SUBDIRS = include src tests examples
+SUBDIRS = include src tests examples stp
pkgconfigdir = $(libdir)/pkgconfig
pkgconfig_DATA = libosmo-sccp.pc libosmo-mtp.pc libosmo-sigtran.pc libosmo-xua.pc
diff --git a/configure.ac b/configure.ac
index 6dc0ebd..82c7ee8 100644
--- a/configure.ac
+++ b/configure.ac
@@ -70,5 +70,6 @@ AC_OUTPUT(
tests/xua/Makefile
tests/ss7/Makefile
examples/Makefile
+ stp/Makefile
Makefile)
diff --git a/include/osmocom/sigtran/osmo_ss7.h b/include/osmocom/sigtran/osmo_ss7.h
index 5becc0e..dff206d 100644
--- a/include/osmocom/sigtran/osmo_ss7.h
+++ b/include/osmocom/sigtran/osmo_ss7.h
@@ -9,6 +9,8 @@
#include <osmocom/core/msgb.h>
#include <osmocom/core/prim.h>
+extern struct llist_head osmo_ss7_xua_servers;
+
struct osmo_ss7_instance;
struct osmo_ss7_user;
struct osmo_sccp_instance;
diff --git a/src/osmo_ss7.c b/src/osmo_ss7.c
index bb13b43..7ed216a 100644
--- a/src/osmo_ss7.c
+++ b/src/osmo_ss7.c
@@ -28,6 +28,7 @@
#include <osmocom/sigtran/osmo_ss7.h>
#include <osmocom/sigtran/mtp_sap.h>
+#include <osmocom/sigtran/protocol/mtp.h>
#include <osmocom/sigtran/protocol/sua.h>
#include <osmocom/sigtran/protocol/m3ua.h>
@@ -52,7 +53,7 @@
static bool ss7_initialized = false;
static LLIST_HEAD(ss7_instances);
-static LLIST_HEAD(ss7_xua_servers);
+LLIST_HEAD(osmo_ss7_xua_servers);
static int32_t next_rctx = 1;
static int32_t next_l_rk_id = 1;
@@ -1539,7 +1540,7 @@ osmo_ss7_xua_server_find(struct osmo_ss7_instance *inst, enum osmo_ss7_asp_proto
struct osmo_xua_server *xs;
OSMO_ASSERT(ss7_initialized);
- llist_for_each_entry(xs, &ss7_xua_servers, list) {
+ llist_for_each_entry(xs, &osmo_ss7_xua_servers, list) {
if (proto == xs->cfg.proto &&
local_port == xs->cfg.local.port)
return xs;
@@ -1589,7 +1590,7 @@ osmo_ss7_xua_server_create(struct osmo_ss7_instance *inst, enum osmo_ss7_asp_pro
}
oxs->inst = inst;
- llist_add_tail(&oxs->list, &ss7_xua_servers);
+ llist_add_tail(&oxs->list, &osmo_ss7_xua_servers);
return oxs;
}
diff --git a/stp/Makefile.am b/stp/Makefile.am
new file mode 100644
index 0000000..81aa11c
--- /dev/null
+++ b/stp/Makefile.am
@@ -0,0 +1,11 @@
+AM_CPPFLAGS = $(all_includes) -I$(top_srcdir)/include
+AM_CFLAGS=-Wall -g $(LIBOSMOCORE_CFLAGS) $(LIBOSMOVTY_CFLAGS) $(LIBOSMONETIF_CFLAGS) $(COVERAGE_FLAGS)
+AM_LDFLAGS=$(COVERAGE_LDFLAGS)
+
+EXTRA_DIST = internal.h
+
+bin_PROGRAMS = osmo-stp
+
+osmo_stp_SOURCES = stp_main.c osmo_ss7_vty.c
+osmo_stp_LDADD = $(top_builddir)/src/libosmo-sigtran.la \
+ $(LIBOSMOCORE_LIBS) $(LIBOSMOVTY_LIBS)
diff --git a/stp/internal.h b/stp/internal.h
new file mode 100644
index 0000000..0a434cc
--- /dev/null
+++ b/stp/internal.h
@@ -0,0 +1,18 @@
+#pragma once
+
+#include <osmocom/vty/command.h>
+
+enum stp_vty_node {
+ L_CS7_AS_NODE = _LAST_OSMOVTY_NODE + 1,
+ L_CS7_ASP_NODE,
+ L_CS7_SUA_NODE,
+ L_CS7_M3UA_NODE,
+ L_CS7_RTABLE_NODE,
+};
+
+int osmo_ss7_vty_init(void);
+int osmo_ss7_vty_go_parent(struct vty *vty);
+int osmo_ss7_is_config_node(struct vty *vty, int node);
+
+extern struct osmo_ss7_instance *g_s7i;
+
diff --git a/src/osmo_ss7_vty.c b/stp/osmo_ss7_vty.c
index 80cd4d0..905c4f6 100644
--- a/src/osmo_ss7_vty.c
+++ b/stp/osmo_ss7_vty.c
@@ -33,6 +33,9 @@
#include <osmocom/vty/misc.h>
#include <osmocom/sigtran/osmo_ss7.h>
+#include <osmocom/sigtran/protocol/mtp.h>
+
+#include "internal.h"
#define CS7_STR "ITU-T Signaling System 7\n"
#define PC_STR "Point Code\n"
@@ -58,7 +61,7 @@ DEFUN(cs7_net_ind, cs7_net_ind_cmd,
"Reserved Network\n"
"Spare Network\n")
{
- struct osmo_ss7_instance *inst = FIXME;
+ struct osmo_ss7_instance *inst = g_s7i;
int ni = get_string_value(ss7_network_indicator_vals, argv[0]);
inst->cfg.network_indicator = ni;
@@ -67,13 +70,13 @@ DEFUN(cs7_net_ind, cs7_net_ind_cmd,
/* TODO: cs7 point-code format */
DEFUN(cs7_pc_format, cs7_pc_format_cmd,
- "cs7 point-code format <1-24> [<1-23> [<1-22>]]",
+ "cs7 point-code format <1-24> [<1-23>] [<1-22>]",
CS7_STR PC_STR "Configure Point Code Format\n"
"Length of first PC component\n"
"Length of second PC component\n"
"Length of third PC component\n")
{
- struct osmo_ss7_instance *inst = FIXME;
+ struct osmo_ss7_instance *inst = g_s7i;
int argind = 0;
inst->cfg.pc_fmt.component_len[0] = atoi(argv[argind++]);
@@ -96,7 +99,7 @@ DEFUN(cs7_pc_format_def, cs7_pc_format_def_cmd,
CS7_STR PC_STR "Configure Point Code Format\n"
"Default Point Code Format (3.8.3)\n")
{
- struct osmo_ss7_instance *inst = FIXME;
+ struct osmo_ss7_instance *inst = g_s7i;
inst->cfg.pc_fmt.component_len[0] = 3;
inst->cfg.pc_fmt.component_len[1] = 8;
inst->cfg.pc_fmt.component_len[2] = 3;
@@ -111,7 +114,7 @@ DEFUN(cs7_pc_delimiter, cs7_pc_delimiter_cmd,
"Use dot as delimiter\n"
"User dash as delimiter\n")
{
- struct osmo_ss7_instance *inst = FIXME;
+ struct osmo_ss7_instance *inst = g_s7i;
if (!strcmp(argv[0], "dash"))
inst->cfg.pc_fmt.delimiter = '-';
@@ -126,7 +129,7 @@ DEFUN(cs7_point_code, cs7_point_code_cmd,
CS7_STR "Configure the local Point Code\n"
"Point Code\n")
{
- struct osmo_ss7_instance *inst = FIXME;
+ struct osmo_ss7_instance *inst = g_s7i;
uint32_t pc = osmo_ss7_pointcode_parse(inst, argv[0]);
inst->cfg.primary_pc = pc;
@@ -136,6 +139,40 @@ DEFUN(cs7_point_code, cs7_point_code_cmd,
/* TODO: cs7 capability-pc */
+static void write_one_ss7_inst(struct vty *vty, struct osmo_ss7_instance *inst)
+{
+ if (inst->cfg.network_indicator)
+ vty_out(vty, "cs7 network-indicator %s%s",
+ get_value_string(ss7_network_indicator_vals,
+ inst->cfg.network_indicator),
+ VTY_NEWLINE);
+
+ if (inst->cfg.pc_fmt.component_len[0] != 3 ||
+ inst->cfg.pc_fmt.component_len[1] != 8 ||
+ inst->cfg.pc_fmt.component_len[2] != 3) {
+ vty_out(vty, "cs7 point-code format %u",
+ inst->cfg.pc_fmt.component_len[0]);
+ if (inst->cfg.pc_fmt.component_len[1])
+ vty_out(vty, " %u", inst->cfg.pc_fmt.component_len[1]);
+ if (inst->cfg.pc_fmt.component_len[2])
+ vty_out(vty, " %u", inst->cfg.pc_fmt.component_len[2]);
+ vty_out(vty, "%s", VTY_NEWLINE);
+ }
+
+ if (inst->cfg.pc_fmt.delimiter != '.')
+ vty_out(vty, "cs7 point-code delimiter dash%s", VTY_NEWLINE);
+
+ if (inst->cfg.primary_pc)
+ vty_out(vty, "cs7 point-code %s%s",
+ osmo_ss7_pointcode_print(inst, inst->cfg.primary_pc),
+ VTY_NEWLINE);
+}
+
+static void config_write_cs7(struct vty *vty)
+{
+ write_one_ss7_inst(vty, g_s7i);
+}
+
/***********************************************************************
* Routing Table Configuration
***********************************************************************/
@@ -151,7 +188,7 @@ DEFUN(cs7_route_table, cs7_route_table_cmd,
CS7_STR "Specify the name of the route table\n"
"Name of the route table\n")
{
- struct osmo_ss7_instance *inst = FIXME;
+ struct osmo_ss7_instance *inst = g_s7i;
struct osmo_ss7_route_table *rtable;
rtable = inst->rtable_system;
@@ -163,7 +200,7 @@ DEFUN(cs7_route_table, cs7_route_table_cmd,
}
DEFUN(cs7_rt_upd, cs7_rt_upd_cmd,
- "update route POINT_CODE [MASK | LENGTH] linkset LS_NAME [priority PRIO] [qos-class (CLASS | default",
+ "update route POINT_CODE MASK linkset LS_NAME [priority PRIO] [qos-class (CLASS|default)]",
"Update the Route\n"
"Update the Route\n"
"Destination Point Code\n"
@@ -185,8 +222,11 @@ DEFUN(cs7_rt_upd, cs7_rt_upd_cmd,
unsigned int argind;
rt = osmo_ss7_route_create(rtable, dpc, mask, ls_name);
- if (!rt)
+ if (!rt) {
+ vty_out(vty, "cannot create route %s/%s to %s%s",
+ argv[0], argv[1], argv[2], VTY_NEWLINE);
return CMD_WARNING;
+ }
argind = 3;
if (argc > argind && !strcmp(argv[argind], "priority")) {
@@ -203,7 +243,7 @@ DEFUN(cs7_rt_upd, cs7_rt_upd_cmd,
}
DEFUN(cs7_rt_rem, cs7_rt_rem_cmd,
- "remove route POINT_CODE [MASK | LENGTH]",
+ "remove route POINT_CODE MASK",
"Remove a Route\n"
"Remove a Route\n"
"Destination Point Code\n"
@@ -216,19 +256,22 @@ DEFUN(cs7_rt_rem, cs7_rt_rem_cmd,
uint32_t mask = osmo_ss7_pointcode_parse_mask_or_len(rtable->inst, argv[1]);
rt = osmo_ss7_route_find_dpc_mask(rtable, dpc, mask);
- if (!rt)
+ if (!rt) {
+ vty_out(vty, "cannot find route to be deleted%s", VTY_NEWLINE);
return CMD_WARNING;
+ }
osmo_ss7_route_destroy(rt);
return CMD_SUCCESS;
}
-static int config_write_rtable(struct vty *vty)
+static void write_one_rtable(struct vty *vty, struct osmo_ss7_route_table *rtable)
{
- struct osmo_ss7_route_table *rtable = vty->index;
struct osmo_ss7_route *rt;
vty_out(vty, "cs7 route-table %s%s", rtable->cfg.name, VTY_NEWLINE);
+ if (rtable->cfg.description)
+ vty_out(vty, " description %s%s", rtable->cfg.description, VTY_NEWLINE);
llist_for_each_entry(rt, &rtable->routes, list) {
vty_out(vty, " update route %s %s linkset %s",
osmo_ss7_pointcode_print(rtable->inst, rt->cfg.pc),
@@ -240,6 +283,16 @@ static int config_write_rtable(struct vty *vty)
vty_out(vty, " qos-class %u", rt->cfg.qos_class);
vty_out(vty, "%s", VTY_NEWLINE);
}
+}
+
+static int config_write_rtable(struct vty *vty)
+{
+ struct osmo_ss7_instance *inst = g_s7i;
+ struct osmo_ss7_route_table *rtable;
+
+ llist_for_each_entry(rtable, &inst->rtable_list, list)
+ write_one_rtable(vty, rtable);
+
return 0;
}
@@ -259,7 +312,7 @@ DEFUN(cs7_sua, cs7_sua_cmd,
"Configure/Enable SUA\n"
"SCTP Port number for SUA\n")
{
- struct osmo_ss7_instance *inst = FIXME;
+ struct osmo_ss7_instance *inst = g_s7i;
struct osmo_xua_server *xs;
uint16_t port = atoi(argv[0]);
@@ -275,6 +328,24 @@ DEFUN(cs7_sua, cs7_sua_cmd,
return CMD_SUCCESS;
}
+DEFUN(no_cs7_sua, no_cs7_sua_cmd,
+ "no cs7 sua <0-65534>",
+ NO_STR CS7_STR "Disable SUA on given SCTP Port\n"
+ "SCTP Port number for SUA\n")
+{
+ struct osmo_ss7_instance *inst = g_s7i;
+ struct osmo_xua_server *xs;
+ uint16_t port = atoi(argv[0]);
+
+ xs = osmo_ss7_xua_server_find(inst, OSMO_SS7_ASP_PROT_SUA, port);
+ if (!xs) {
+ vty_out(vty, "No SUA server for port %u found%s", port, VTY_NEWLINE);
+ return CMD_WARNING;
+ }
+ osmo_ss7_xua_server_destroy(xs);
+ return CMD_SUCCESS;
+}
+
DEFUN(sua_local_ip, sua_local_ip_cmd,
"local-ip A.B.C.D",
"Configure the Local IP Address for SUA\n"
@@ -291,12 +362,22 @@ enum osmo_ss7_asp_protocol parse_asp_proto(const char *protocol)
return get_string_value(osmo_ss7_asp_protocol_vals, protocol);
}
+static void write_one_sua(struct vty *vty, struct osmo_xua_server *xs)
+{
+ vty_out(vty, "cs7 %s %u%s",
+ get_value_string(osmo_ss7_asp_protocol_vals, xs->cfg.proto),
+ xs->cfg.local.port, VTY_NEWLINE);
+ vty_out(vty, " local-ip %s%s", xs->cfg.local.host, VTY_NEWLINE);
+}
+
+
static int config_write_sua(struct vty *vty)
{
- struct osmo_xua_server *xs = vty->index;
+ struct osmo_xua_server *xs;
+
+ llist_for_each_entry(xs, &osmo_ss7_xua_servers, list)
+ write_one_sua(vty, xs);
- vty_out(vty, "cs7 sua %u%s", xs->cfg.local.port, VTY_NEWLINE);
- vty_out(vty, " local-ip %s%s", xs->cfg.local.host, VTY_NEWLINE);
return 0;
}
@@ -316,7 +397,7 @@ DEFUN(cs7_m3ua, cs7_m3ua_cmd,
"Configure/Enable M3UA\n"
"SCTP Port number for M3UA\n")
{
- struct osmo_ss7_instance *inst = FIXME;
+ struct osmo_ss7_instance *inst = g_s7i;
struct osmo_xua_server *xs;
uint16_t port = atoi(argv[0]);
@@ -332,6 +413,24 @@ DEFUN(cs7_m3ua, cs7_m3ua_cmd,
return CMD_SUCCESS;
}
+DEFUN(no_cs7_m3ua, no_cs7_m3ua_cmd,
+ "no cs7 m3ua <0-65534>",
+ NO_STR CS7_STR "Disable M3UA on given SCTP Port\n"
+ "SCTP Port number for M3UA\n")
+{
+ struct osmo_ss7_instance *inst = g_s7i;
+ struct osmo_xua_server *xs;
+ uint16_t port = atoi(argv[0]);
+
+ xs = osmo_ss7_xua_server_find(inst, OSMO_SS7_ASP_PROT_M3UA, port);
+ if (!xs) {
+ vty_out(vty, "No M3UA server for port %u found%s", port, VTY_NEWLINE);
+ return CMD_WARNING;
+ }
+ osmo_ss7_xua_server_destroy(xs);
+ return CMD_SUCCESS;
+}
+
DEFUN(m3ua_local_ip, m3ua_local_ip_cmd,
"local-ip A.B.C.D",
"Configure the Local IP Address for M3UA\n"
@@ -345,10 +444,7 @@ DEFUN(m3ua_local_ip, m3ua_local_ip_cmd,
static int config_write_m3ua(struct vty *vty)
{
- struct osmo_xua_server *xs = vty->index;
-
- vty_out(vty, "cs7 m3ua %u%s", xs->cfg.local.port, VTY_NEWLINE);
- vty_out(vty, " local-ip %s%s", xs->cfg.local.host, VTY_NEWLINE);
+ /* see config_write_sua */
return 0;
}
@@ -363,7 +459,7 @@ static struct cmd_node asp_node = {
};
DEFUN(cs7_asp, cs7_asp_cmd,
- "cs7 asp NAME <0-65535> <0-65535> [m3ua | sua]",
+ "cs7 asp NAME <0-65535> <0-65535> (m3ua|sua)",
CS7_STR
"Configure Application Server Process\n"
"Name of ASP\n"
@@ -372,19 +468,24 @@ DEFUN(cs7_asp, cs7_asp_cmd,
"M3UA Protocol\n"
"SUA Protocol\n")
{
- struct osmo_ss7_instance *inst = FIXME;
+ struct osmo_ss7_instance *inst = g_s7i;
const char *name = argv[0];
uint16_t remote_port = atoi(argv[1]);
uint16_t local_port = atoi(argv[2]);
enum osmo_ss7_asp_protocol protocol = parse_asp_proto(argv[3]);
struct osmo_ss7_asp *asp;
- if (protocol == OSMO_SS7_ASP_PROT_NONE)
+ if (protocol == OSMO_SS7_ASP_PROT_NONE) {
+ vty_out(vty, "invalid protocol '%s'%s", argv[3], VTY_NEWLINE);
return CMD_WARNING;
+ }
asp = osmo_ss7_asp_find_or_create(inst, name, remote_port, local_port, protocol);
- if (!asp)
+ if (!asp) {
+ vty_out(vty, "cannot create ASP '%s'%s", name, VTY_NEWLINE);
return CMD_WARNING;
+ }
+ asp->cfg.is_server = true;
vty->node = L_CS7_ASP_NODE;
vty->index = asp;
@@ -392,9 +493,27 @@ DEFUN(cs7_asp, cs7_asp_cmd,
return CMD_SUCCESS;
}
+DEFUN(no_cs7_asp, no_cs7_asp_cmd,
+ "no cs7 asp NAME",
+ NO_STR CS7_STR "Disable Application Server Process\n"
+ "Name of ASP\n")
+{
+ struct osmo_ss7_instance *inst = g_s7i;
+ const char *name = argv[0];
+ struct osmo_ss7_asp *asp;
+
+ asp = osmo_ss7_asp_find_by_name(inst, name);
+ if (!asp) {
+ vty_out(vty, "No ASP named '%s' found%s", name, VTY_NEWLINE);
+ return CMD_WARNING;
+ }
+ osmo_ss7_asp_destroy(asp);
+ return CMD_SUCCESS;
+}
+
DEFUN(asp_remote_ip, asp_remote_ip_cmd,
"remote-ip A.B.C.D",
- "Specity Remote IP Address of ASP\n"
+ "Specify Remote IP Address of ASP\n"
"Remote IP Address of ASP\n")
{
struct osmo_ss7_asp *asp = vty->index;
@@ -404,7 +523,7 @@ DEFUN(asp_remote_ip, asp_remote_ip_cmd,
DEFUN(asp_qos_clas, asp_qos_class_cmd,
"qos-class <0-255>",
- "Specity QoS Class of ASP\n"
+ "Specify QoS Class of ASP\n"
"QoS Class of ASP\n")
{
struct osmo_ss7_asp *asp = vty->index;
@@ -416,8 +535,8 @@ DEFUN(asp_block, asp_block_cmd,
"block",
"Allows a SCTP Association with ASP, but doesn't let it become active\n")
{
- struct osmo_ss7_asp *asp = vty->index;
- vty_out(vty, "Not supported yet\n");
+ /* TODO */
+ vty_out(vty, "Not supported yet%s", VTY_NEWLINE);
return CMD_WARNING;
}
@@ -425,24 +544,35 @@ DEFUN(asp_shutdown, asp_shutdown_cmd,
"shutdown",
"Terminates SCTP association; New associations will be rejected\n")
{
- struct osmo_ss7_asp *asp = vty->index;
- vty_out(vty, "Not supported yet\n");
+ /* TODO */
+ vty_out(vty, "Not supported yet%s", VTY_NEWLINE);
return CMD_WARNING;
}
-static int config_write_asp(struct vty *vty)
+static void write_one_asp(struct vty *vty, struct osmo_ss7_asp *asp)
{
- struct osmo_ss7_asp *asp = vty->index;
-
vty_out(vty, "cs7 asp %s %u %u %s%s",
asp->cfg.name, asp->cfg.remote.port, asp->cfg.local.port,
osmo_ss7_asp_protocol_name(asp->cfg.proto), VTY_NEWLINE);
+ if (asp->cfg.description)
+ vty_out(vty, " description %s%s", asp->cfg.description, VTY_NEWLINE);
vty_out(vty, " remote-ip %s%s", asp->cfg.remote.host, VTY_NEWLINE);
if (asp->cfg.qos_class)
vty_out(vty, " qos-class %u%s", asp->cfg.qos_class, VTY_NEWLINE);
+}
+
+static int config_write_asp(struct vty *vty)
+{
+ struct osmo_ss7_instance *inst = g_s7i;
+ struct osmo_ss7_asp *asp;
+
+ llist_for_each_entry(asp, &inst->asp_list, list)
+ write_one_asp(vty, asp);
+
return 0;
}
+
/***********************************************************************
* Application Server
***********************************************************************/
@@ -454,21 +584,29 @@ static struct cmd_node as_node = {
};
DEFUN(cs7_as, cs7_as_cmd,
- "cs7 as NAME [m3ua | sua]",
+ "cs7 as NAME (m3ua|sua)",
CS7_STR
"Configure an Application Server\n"
"Name of the Application Server\n"
"M3UA Application Server\n"
"SUA Application Server\n")
{
+ struct osmo_ss7_instance *inst = g_s7i;
struct osmo_ss7_as *as;
const char *name = argv[0];
enum osmo_ss7_asp_protocol protocol = parse_asp_proto(argv[1]);
- if (protocol == OSMO_SS7_ASP_PROT_NONE)
+ if (protocol == OSMO_SS7_ASP_PROT_NONE) {
+ vty_out(vty, "invalid protocol '%s'%s", argv[3], VTY_NEWLINE);
return CMD_WARNING;
+ }
+
+ as = osmo_ss7_as_find_or_create(inst, name, protocol);
+ if (!as) {
+ vty_out(vty, "cannot create AS '%s'%s", name, VTY_NEWLINE);
+ return CMD_WARNING;
+ }
- /* FIXME */
as->cfg.name = talloc_strdup(as, name);
vty->node = L_CS7_AS_NODE;
@@ -478,6 +616,24 @@ DEFUN(cs7_as, cs7_as_cmd,
return CMD_SUCCESS;
}
+DEFUN(no_cs7_as, no_cs7_as_cmd,
+ "no cs7 as NAME",
+ NO_STR CS7_STR "Disable Application Server\n"
+ "Name of AS\n")
+{
+ struct osmo_ss7_instance *inst = g_s7i;
+ const char *name = argv[0];
+ struct osmo_ss7_as *as;
+
+ as = osmo_ss7_as_find_by_name(inst, name);
+ if (!as) {
+ vty_out(vty, "No AS named '%s' found%s", name, VTY_NEWLINE);
+ return CMD_WARNING;
+ }
+ osmo_ss7_as_destroy(as);
+ return CMD_SUCCESS;
+}
+
/* TODO: routing-key */
DEFUN(as_asp, as_asp_cmd,
"asp NAME",
@@ -486,8 +642,10 @@ DEFUN(as_asp, as_asp_cmd,
{
struct osmo_ss7_as *as = vty->index;
- if (osmo_ss7_as_add_asp(as, argv[0]))
+ if (osmo_ss7_as_add_asp(as, argv[0])) {
+ vty_out(vty, "cannot find ASP '%s'%s", argv[0], VTY_NEWLINE);
return CMD_WARNING;
+ }
return CMD_SUCCESS;
}
@@ -499,8 +657,10 @@ DEFUN(as_no_asp, as_no_asp_cmd,
{
struct osmo_ss7_as *as = vty->index;
- if (osmo_ss7_as_del_asp(as, argv[0]))
+ if (osmo_ss7_as_del_asp(as, argv[0])) {
+ vty_out(vty, "cannot find ASP '%s'%s", argv[0], VTY_NEWLINE);
return CMD_WARNING;
+ }
return CMD_SUCCESS;
}
@@ -516,7 +676,7 @@ DEFUN(as_traf_mode, as_traf_mode_cmd,
struct osmo_ss7_as *as = vty->index;
as->cfg.mode = get_string_value(osmo_ss7_as_traffic_mode_vals, argv[0]);
- return CMD_WARNING;
+ return CMD_SUCCESS;
}
DEFUN(as_recov_tout, as_recov_tout_cmd,
@@ -554,7 +714,7 @@ const struct value_string mtp_si_vals[] = {
};
DEFUN(as_rout_key, as_rout_key_cmd,
- "routing-key RCONTEXT DPC [si {aal2 | bicc | b-isup | h248 | isup | sat-isup | sccp | tup }] [ssn SSN]}",
+ "routing-key RCONTEXT DPC [si (aal2|bicc|b-isup|h248|isup|sat-isup|sccp|tup)] [ssn SSN]}",
"Define a routing key\n"
"Routing context number\n"
"Destination Point Code\n"
@@ -571,25 +731,21 @@ DEFUN(as_rout_key, as_rout_key_cmd,
"Sub-System Number to match on\n")
{
struct osmo_ss7_as *as = vty->index;
- uint32_t key = atoi(argv[0]);
- struct osmo_ss7_routing_key *rkey;
+ struct osmo_ss7_routing_key *rkey = &as->cfg.routing_key;
int argind;
- rkey = osmo_ss7_rkey_find_or_create(as, key);
- if (!rkey)
- return CMD_WARNING;
-
+ rkey->context = atoi(argv[0]);
rkey->pc = osmo_ss7_pointcode_parse(as->inst, argv[1]);
argind = 2;
- if (!strcmp(argv[argind], "si")) {
+ if (argind < argc && !strcmp(argv[argind], "si")) {
const char *si_str;
argind++;
si_str = argv[argind++];
/* parse numeric SI from string */
rkey->si = get_string_value(mtp_si_vals, si_str);
}
- if (!strcmp(argv[argind], "ssn")) {
+ if (argind < argc && !strcmp(argv[argind], "ssn")) {
argind++;
rkey->ssn = atoi(argv[argind]);
}
@@ -597,14 +753,15 @@ DEFUN(as_rout_key, as_rout_key_cmd,
return CMD_SUCCESS;
}
-static int config_write_as(struct vty *vty)
+static void write_one_as(struct vty *vty, struct osmo_ss7_as *as)
{
- struct osmo_ss7_as *as = vty->index;
struct osmo_ss7_routing_key *rkey;
unsigned int i;
vty_out(vty, "cs7 as %s %s%s", as->cfg.name,
osmo_ss7_asp_protocol_name(as->cfg.proto), VTY_NEWLINE);
+ if (as->cfg.description)
+ vty_out(vty, " description %s%s", as->cfg.description, VTY_NEWLINE);
for (i = 0; i < ARRAY_SIZE(as->cfg.asps); i++) {
struct osmo_ss7_asp *asp = as->cfg.asps[i];
if (!asp)
@@ -618,7 +775,8 @@ static int config_write_as(struct vty *vty)
vty_out(vty, " recovery-timeout %u%s",
as->cfg.recovery_timeout_msec, VTY_NEWLINE);
}
- vty_out(vty, " qos-class %u%s", as->cfg.qos_class, VTY_NEWLINE);
+ if (as->cfg.qos_class)
+ vty_out(vty, " qos-class %u%s", as->cfg.qos_class, VTY_NEWLINE);
rkey = &as->cfg.routing_key;
vty_out(vty, " routing-key %u %s", rkey->context,
osmo_ss7_pointcode_print(as->inst, rkey->pc));
@@ -628,10 +786,64 @@ static int config_write_as(struct vty *vty)
if (rkey->ssn)
vty_out(vty, " ssn %u", rkey->ssn);
vty_out(vty, "%s", VTY_NEWLINE);
+}
+
+static int config_write_as(struct vty *vty)
+{
+ struct osmo_ss7_instance *inst = g_s7i;
+ struct osmo_ss7_as *as;
+
+ /* HACK to call this here, as we cannot install additional
+ * 'save' code into the root CONFIG_NODE ... */
+ config_write_cs7(vty);
+
+ /* HACK to call this here, but we must make sure that the ASP
+ * are all configured before we reference them from the AS, and
+ * VTY code always stores the nodes in alphabetical order */
+
+ config_write_asp(vty);
+
+ llist_for_each_entry(as, &inst->as_list, list)
+ write_one_as(vty, as);
return 0;
}
+int osmo_ss7_vty_go_parent(struct vty *vty)
+{
+ struct osmo_ss7_asp *asp;
+
+ switch (vty->node) {
+ case L_CS7_ASP_NODE:
+ asp = vty->index;
+ osmo_ss7_asp_restart(asp);
+ vty->node = CONFIG_NODE;
+ break;
+ case L_CS7_RTABLE_NODE:
+ case L_CS7_SUA_NODE:
+ case L_CS7_M3UA_NODE:
+ case L_CS7_AS_NODE:
+ default:
+ vty->node = CONFIG_NODE;
+ break;
+ }
+ return 0;
+}
+
+int osmo_ss7_is_config_node(struct vty *vty, int node)
+{
+ switch (node) {
+ case L_CS7_ASP_NODE:
+ case L_CS7_RTABLE_NODE:
+ case L_CS7_SUA_NODE:
+ case L_CS7_M3UA_NODE:
+ case L_CS7_AS_NODE:
+ return 1;
+ default:
+ return 0;
+ }
+}
+
int osmo_ss7_vty_init(void)
{
install_element(CONFIG_NODE, &cs7_net_ind_cmd);
@@ -650,16 +862,19 @@ int osmo_ss7_vty_init(void)
install_node(&sua_node, config_write_sua);
vty_install_default(L_CS7_SUA_NODE);
install_element(CONFIG_NODE, &cs7_sua_cmd);
+ install_element(CONFIG_NODE, &no_cs7_sua_cmd);
install_element(L_CS7_SUA_NODE, &sua_local_ip_cmd);
install_node(&m3ua_node, config_write_m3ua);
vty_install_default(L_CS7_M3UA_NODE);
install_element(CONFIG_NODE, &cs7_m3ua_cmd);
+ install_element(CONFIG_NODE, &no_cs7_m3ua_cmd);
install_element(L_CS7_M3UA_NODE, &m3ua_local_ip_cmd);
- install_node(&asp_node, config_write_asp);
+ install_node(&asp_node, NULL);
vty_install_default(L_CS7_ASP_NODE);
install_element(CONFIG_NODE, &cs7_asp_cmd);
+ install_element(CONFIG_NODE, &no_cs7_asp_cmd);
install_element(L_CS7_ASP_NODE, &cfg_description_cmd);
install_element(L_CS7_ASP_NODE, &asp_remote_ip_cmd);
install_element(L_CS7_ASP_NODE, &asp_qos_class_cmd);
@@ -669,6 +884,7 @@ int osmo_ss7_vty_init(void)
install_node(&as_node, config_write_as);
vty_install_default(L_CS7_AS_NODE);
install_element(CONFIG_NODE, &cs7_as_cmd);
+ install_element(CONFIG_NODE, &no_cs7_as_cmd);
install_element(L_CS7_AS_NODE, &cfg_description_cmd);
install_element(L_CS7_AS_NODE, &as_asp_cmd);
install_element(L_CS7_AS_NODE, &as_no_asp_cmd);
diff --git a/stp/stp_main.c b/stp/stp_main.c
new file mode 100644
index 0000000..029c0b2
--- /dev/null
+++ b/stp/stp_main.c
@@ -0,0 +1,101 @@
+/* Osmocom STP (Signal Transfer Point) */
+
+/* (C) 2015-2017 by Harald Welte <laforge@gnumonks.org>
+ * All Rights Reserved
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ *
+ */
+
+#include <stdlib.h>
+#include <stdio.h>
+#include <string.h>
+#include <unistd.h>
+
+#include <osmocom/core/select.h>
+#include <osmocom/core/utils.h>
+#include <osmocom/core/logging.h>
+#include <osmocom/core/application.h>
+#include <osmocom/core/fsm.h>
+#include <osmocom/vty/vty.h>
+#include <osmocom/vty/ports.h>
+#include <osmocom/vty/telnet_interface.h>
+
+#include <osmocom/sigtran/osmo_ss7.h>
+#include <osmocom/sigtran/sccp_sap.h>
+#include <osmocom/sigtran/sccp_helpers.h>
+#include <osmocom/sigtran/protocol/sua.h>
+#include <osmocom/sigtran/protocol/m3ua.h>
+
+#include "internal.h"
+
+struct osmo_ss7_instance *g_s7i;
+
+static const struct log_info_cat log_info_cat[] = {
+};
+
+static const struct log_info log_info = {
+ .cat = log_info_cat,
+ .num_cat = ARRAY_SIZE(log_info_cat),
+};
+
+/* Hack to enable debug logging for all relevant (used?) subsystems */
+static void init_logging(void)
+{
+ const int log_cats[] = { DLSS7, DLSUA, DLM3UA, DLSCCP, DLINP };
+ unsigned int i;
+
+ osmo_init_logging(&log_info);
+
+ for (i = 0; i < ARRAY_SIZE(log_cats); i++)
+ log_set_category_filter(osmo_stderr_target, log_cats[i], 1, LOGL_DEBUG);
+}
+
+static struct vty_app_info vty_info = {
+ .name = "osmo-stp",
+ .version = PACKAGE_VERSION,
+ .go_parent_cb = osmo_ss7_vty_go_parent,
+ .is_config_node = osmo_ss7_is_config_node,
+};
+
+int main(int argc, char **argv)
+{
+ char *config_file = "osmo-stp.cfg";
+ int rc;
+
+ init_logging();
+ osmo_ss7_init();
+ osmo_fsm_log_addr(false);
+ vty_init(&vty_info);
+ osmo_ss7_vty_init();
+
+ g_s7i = osmo_ss7_instance_find_or_create(NULL, 0);
+
+ rc = vty_read_config_file(config_file, NULL);
+ if (rc < 0) {
+ fprintf(stderr, "Failed to parse the config file '%s'\n",
+ config_file);
+ exit(1);
+ }
+
+ rc = telnet_init_dynif(NULL, NULL, vty_get_bind_addr(), OSMO_VTY_PORT_STP);
+ if (rc < 0) {
+ perror("Erro binding VTY port\n");
+ exit(1);
+ }
+
+ while (1) {
+ osmo_select_main(0);
+ }
+}