aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorHolger Hans Peter Freyther <zecke@selfish.org>2011-02-22 20:57:08 +0100
committerHolger Hans Peter Freyther <zecke@selfish.org>2011-02-23 15:25:35 +0100
commit7176030e02ca59d5b4ee015f24ee2bf733eeed8e (patch)
treeeed6a2bb6bd74d365a09e77cbdc875bfcac689ed
parent2917644d503b706f0df5cf7228fc284a79436e31 (diff)
vty: Add all mighty new vty interface for osmo-stp
This new interface allows to have multiple linksets, msc connections and ways to connect those in one instance of the osmo-stp. Forbid to reset linksets without an app.
-rw-r--r--include/bsc_data.h10
-rw-r--r--include/mtp_data.h1
-rw-r--r--include/sctp_m2ua.h7
-rw-r--r--include/snmp_mtp.h3
-rw-r--r--include/ss7_application.h2
-rw-r--r--include/ss7_vty.h42
-rw-r--r--src/Makefile.am5
-rw-r--r--src/bsc.c5
-rw-r--r--src/link_udp.c78
-rw-r--r--src/links.c22
-rw-r--r--src/main_stp.c97
-rw-r--r--src/mtp_layer3.c3
-rw-r--r--src/sctp_m2ua.c55
-rw-r--r--src/snmp_mtp.c22
-rw-r--r--src/ss7_application.c8
-rw-r--r--src/vty_interface.c887
-rw-r--r--src/vty_interface_cmds.c13
-rw-r--r--src/vty_interface_legacy.c358
18 files changed, 1301 insertions, 317 deletions
diff --git a/include/bsc_data.h b/include/bsc_data.h
index 12e8e93..3588ac8 100644
--- a/include/bsc_data.h
+++ b/include/bsc_data.h
@@ -53,6 +53,7 @@ struct mtp_udp_link {
int link_index;
int reset_timeout;
+ char *dest;
struct sockaddr_in remote;
struct mtp_udp_data *data;
@@ -69,11 +70,13 @@ struct bsc_data {
/* udp code */
struct mtp_udp_data udp_data;
- int src_port;
+ int udp_src_port;
int udp_port;
char *udp_ip;
int udp_nr_links;
+ int m2ua_src_port;
+
/* MTP Links */
struct llist_head linksets;
int num_linksets;
@@ -104,7 +107,8 @@ void mtp_linkset_up(struct mtp_link_set *);
/* udp init */
struct mtp_link_set *link_set_create(struct bsc_data *bsc);
-int link_global_init(struct mtp_udp_data *data, int src_port);
+int link_global_init(struct mtp_udp_data *data);
+int link_global_bind(struct mtp_udp_data *data, int src_port);
int link_udp_init(struct mtp_udp_link *data, char *dest_ip, int port);
int link_init(struct bsc_data *bsc, struct mtp_link_set *set);
int link_shutdown_all(struct mtp_link_set *);
@@ -120,4 +124,6 @@ int mtp_handle_pcap(struct mtp_link *, int dir, const uint8_t *data, int length)
struct bsc_data *bsc_data_create();
+struct mtp_udp_link *mtp_udp_link_init(struct mtp_link *link);
+
#endif
diff --git a/include/mtp_data.h b/include/mtp_data.h
index 969a4de..bbd013e 100644
--- a/include/mtp_data.h
+++ b/include/mtp_data.h
@@ -84,6 +84,7 @@ struct mtp_link_set {
struct rate_ctr_group *ctrg;
/* custom data */
+ struct bsc_data *bsc;
struct ss7_application *app;
};
diff --git a/include/sctp_m2ua.h b/include/sctp_m2ua.h
index 34c8666..2ae1472 100644
--- a/include/sctp_m2ua.h
+++ b/include/sctp_m2ua.h
@@ -57,6 +57,8 @@ struct mtp_m2ua_link {
int link_index;
struct llist_head entry;
struct sctp_m2ua_transport *transport;
+
+ char *as;
};
/*
@@ -71,8 +73,11 @@ struct sctp_m2ua_conn {
struct sctp_m2ua_transport *trans;
};
-struct sctp_m2ua_transport *sctp_m2ua_transp_create(const char *ip, int port);
+struct sctp_m2ua_transport *sctp_m2ua_transp_create(struct bsc_data *bsc);
+int sctp_m2ua_transport_bind(struct sctp_m2ua_transport *, const char *ip, int port);
struct mtp_m2ua_link *mtp_m2ua_link_create(struct sctp_m2ua_transport *transport,
struct mtp_link_set *);
+struct mtp_m2ua_link *mtp_m2ua_link_init(struct mtp_link *link);
+
#endif
diff --git a/include/snmp_mtp.h b/include/snmp_mtp.h
index 8c15df7..0c3075f 100644
--- a/include/snmp_mtp.h
+++ b/include/snmp_mtp.h
@@ -49,7 +49,8 @@ enum {
SNMP_STATUS_TIMEOUT,
};
-struct snmp_mtp_session *snmp_mtp_session_create(char *host);
+struct snmp_mtp_session *snmp_mtp_session_create(void);
+int snmp_mtp_peer_name(struct snmp_mtp_session *, char *name);
void snmp_mtp_deactivate(struct snmp_mtp_session *, int link_id);
void snmp_mtp_activate(struct snmp_mtp_session *, int link_id);
void snmp_mtp_poll();
diff --git a/include/ss7_application.h b/include/ss7_application.h
index 66ddd87..084a8f7 100644
--- a/include/ss7_application.h
+++ b/include/ss7_application.h
@@ -35,6 +35,7 @@ enum ss7_set_type {
};
enum ss7_app_type {
+ APP_NONE,
APP_CELLMGR,
APP_RELAY,
APP_STP,
@@ -59,6 +60,7 @@ struct ss7_application {
int type;
/* for the routing */
+ int route_is_set;
struct ss7_application_route route_src;
struct ss7_application_route route_dst;
diff --git a/include/ss7_vty.h b/include/ss7_vty.h
new file mode 100644
index 0000000..48dbb48
--- /dev/null
+++ b/include/ss7_vty.h
@@ -0,0 +1,42 @@
+/*
+ * (C) 2011 by Holger Hans Peter Freyther <zecke@selfish.org>
+ * (C) 2011 by On-Waves
+ * All Rights Reserved
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Affero General Public License as published by
+ * the Free Software Foundation, either version 3 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 Affero General Public License for more details.
+ *
+ * You should have received a copy of the GNU Affero General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ *
+ */
+
+#ifndef SS7_VTY_H
+#define SS7_VTY_H
+
+#include <osmocom/vty/vty.h>
+#include <osmocom/vty/buffer.h>
+#include <osmocom/vty/command.h>
+
+enum ss7_vty_node {
+ MGCP_NODE = _LAST_OSMOVTY_NODE + 1,
+ CELLMGR_NODE,
+ SS7_NODE,
+ LINKSETS_NODE,
+ LINK_NODE,
+ MSC_NODE,
+ APP_NODE,
+};
+
+extern struct cmd_element cfg_description_cmd;
+extern struct cmd_element cfg_no_description_cmd;
+
+
+#endif
diff --git a/src/Makefile.am b/src/Makefile.am
index 3b6301a..4930e97 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -13,12 +13,13 @@ cellmgr_ng_SOURCES = main.c mtp_layer3.c thread.c input/ipaccess.c pcap.c \
bss_patch.c bssap_sccp.c bsc_sccp.c bsc_ussd.c links.c \
msc_conn.c link_udp.c snmp_mtp.c debug.c isup.c \
mtp_link.c counter.c sccp_state.c bsc.c ss7_application.c \
- vty_interface.c vty_interface_cmds.c
+ vty_interface_legacy.c vty_interface_cmds.c
cellmgr_ng_LDADD = $(LIBOSMOCORE_LIBS) $(LIBOSMOSCCP_LIBS) $(LIBOSMOVTY_LIBS) $(NEXUSWARE_C7_LIBS) \
-lpthread -lnetsnmp -lcrypto
osmo_stp_SOURCES = main_stp.c mtp_layer3.c thread.c pcap.c link_udp.c snmp_mtp.c \
- debug.c links.c isup.c sctp_m2ua.c \
+ debug.c links.c isup.c sctp_m2ua.c msc_conn.c sccp_state.c \
+ bss_patch.c bssap_sccp.c bsc_sccp.c bsc_ussd.c input/ipaccess.c \
mtp_link.c counter.c bsc.c ss7_application.c \
vty_interface.c vty_interface_cmds.c
osmo_stp_LDADD = $(LIBOSMOCORE_LIBS) $(LIBOSMOSCCP_LIBS) $(LIBOSMOVTY_LIBS) $(NEXUSWARE_C7_LIBS) \
diff --git a/src/bsc.c b/src/bsc.c
index c4a955a..98c2e8d 100644
--- a/src/bsc.c
+++ b/src/bsc.c
@@ -71,10 +71,13 @@ struct bsc_data *bsc_data_create()
bsc->udp_ip = NULL;
bsc->udp_nr_links = 1;
- bsc->src_port = 1313;
+ bsc->udp_src_port = 1313;
bsc->pcap_fd = -1;
bsc->udp_reset_timeout = 180;
+ /* m2ua code */
+ bsc->m2ua_src_port = 2904;
+
return bsc;
}
diff --git a/src/link_udp.c b/src/link_udp.c
index bea67de..69d2ee9 100644
--- a/src/link_udp.c
+++ b/src/link_udp.c
@@ -231,28 +231,12 @@ static int udp_link_start(struct mtp_link *link)
int link_udp_init(struct mtp_udp_link *link, char *remote, int port)
{
- /* setup SNMP first, it is blocking */
- link->session = snmp_mtp_session_create(remote);
- if (!link->session)
- return -1;
- link->session->data = link;
-
- /* function table */
- link->base->shutdown = udp_link_shutdown;
- link->base->clear_queue = udp_link_dummy;
-
- link->base->reset = udp_link_reset;
- link->base->start = udp_link_start;
- link->base->write = udp_link_write;
-
/* prepare the remote */
memset(&link->remote, 0, sizeof(link->remote));
link->remote.sin_family = AF_INET;
link->remote.sin_port = htons(port);
inet_aton(remote, &link->remote.sin_addr);
- /* add it to the list of udp connections */
- llist_add_tail(&link->entry, &link->data->links);
return 0;
}
@@ -263,12 +247,8 @@ static void snmp_poll(void *_data)
bsc_schedule_timer(&data->snmp_poll, 0, 5000);
}
-int link_global_init(struct mtp_udp_data *data, int src_port)
+int link_global_init(struct mtp_udp_data *data)
{
- struct sockaddr_in addr;
- int fd;
- int on;
-
INIT_LLIST_HEAD(&data->links);
write_queue_init(&data->write_queue, 100);
@@ -278,6 +258,15 @@ int link_global_init(struct mtp_udp_data *data, int src_port)
data->write_queue.read_cb = udp_read_cb;
data->write_queue.write_cb = udp_write_cb;
+ return 0;
+}
+
+int link_global_bind(struct mtp_udp_data *data, int src_port)
+{
+ struct sockaddr_in addr;
+ int fd;
+ int on;
+
data->write_queue.bfd.fd = fd = socket(AF_INET, SOCK_DGRAM, 0);
if (fd < 0) {
LOGP(DINP, LOGL_ERROR, "Failed to create UDP socket.\n");
@@ -359,3 +348,50 @@ void snmp_mtp_callback(struct snmp_mtp_session *session,
area, link->nr, link->name, link->set->nr, link->set->name);
}
}
+
+struct mtp_udp_link *mtp_udp_link_init(struct mtp_link *blnk)
+{
+ struct bsc_data *bsc;
+ struct mtp_udp_link *lnk;
+
+ lnk = talloc_zero(blnk, struct mtp_udp_link);
+ if (!lnk) {
+ LOGP(DINP, LOGL_ERROR, "Failed to allocate.\n");
+ return NULL;
+ }
+
+ /* setup SNMP first, it is blocking */
+ lnk->session = snmp_mtp_session_create();
+ if (!lnk->session) {
+ LOGP(DINP, LOGL_ERROR, "Failed to allocate snmp session.\n");
+ talloc_free(lnk);
+ return NULL;
+ }
+ lnk->session->data = lnk;
+
+ bsc = blnk->set->bsc;
+ lnk->data = &bsc->udp_data;
+ lnk->reset_timeout = bsc->udp_reset_timeout;
+
+ lnk->base = blnk;
+ lnk->base->data = lnk;
+ lnk->base->type = SS7_LTYPE_UDP;
+ lnk->bsc = bsc;
+
+ /* function table */
+ lnk->base->shutdown = udp_link_shutdown;
+ lnk->base->clear_queue = udp_link_dummy;
+
+ lnk->base->reset = udp_link_reset;
+ lnk->base->start = udp_link_start;
+ lnk->base->write = udp_link_write;
+
+ /* prepare the remote */
+ memset(&lnk->remote, 0, sizeof(lnk->remote));
+ lnk->remote.sin_family = AF_INET;
+
+ /* add it to the list of udp connections */
+ llist_add_tail(&lnk->entry, &lnk->data->links);
+
+ return lnk;
+}
diff --git a/src/links.c b/src/links.c
index a756a68..09e1c2f 100644
--- a/src/links.c
+++ b/src/links.c
@@ -94,8 +94,6 @@ struct mtp_link_set *link_set_create(struct bsc_data *bsc)
set = mtp_link_set_alloc(bsc);
set->name = talloc_strdup(set, "MTP");
- set->sccp_opc = set->isup_opc = -1;
- set->pcap_fd = bsc->pcap_fd;
set->ni = MTP_NI_NATION_NET;
set->spare = 0;
@@ -116,29 +114,29 @@ int link_init(struct bsc_data *bsc, struct mtp_link_set *set)
struct mtp_link *blnk;
- if (!bsc->src_port) {
+ if (!bsc->udp_src_port) {
LOGP(DINP, LOGL_ERROR, "You need to set a UDP address.\n");
return -1;
}
LOGP(DINP, LOGL_NOTICE, "Using UDP MTP mode.\n");
- if (link_global_init(&bsc->udp_data, bsc->src_port) != 0)
+ if (link_global_init(&bsc->udp_data) != 0)
return -1;
+ if (link_global_bind(&bsc->udp_data, bsc->udp_src_port) != 0)
+ return -1;
for (i = 1; i <= bsc->udp_nr_links; ++i) {
blnk = mtp_link_alloc(set);
- lnk = talloc_zero(blnk, struct mtp_udp_link);
- lnk->base = blnk;
- lnk->base->data = lnk;
- lnk->base->type = SS7_LTYPE_UDP;
- lnk->bsc = bsc;
- lnk->data = &bsc->udp_data;
- lnk->link_index = i;
- lnk->reset_timeout = bsc->udp_reset_timeout;
+ lnk = mtp_udp_link_init(blnk);
+
+ lnk->link_index = 1;
/* now connect to the transport */
+ if (snmp_mtp_peer_name(lnk->session, bsc->udp_ip) != 0)
+ return -1;
+
if (link_udp_init(lnk, bsc->udp_ip, bsc->udp_port) != 0)
return -1;
}
diff --git a/src/main_stp.c b/src/main_stp.c
index 35ec2ed..b87a6cb 100644
--- a/src/main_stp.c
+++ b/src/main_stp.c
@@ -196,9 +196,6 @@ static int inject_init(struct bsc_data *bsc)
int main(int argc, char **argv)
{
int rc;
- struct mtp_link_set *set;
- struct mtp_link_set *m2ua_set;
- struct mtp_m2ua_link *lnk;
struct ss7_application *app;
thread_init();
@@ -227,38 +224,7 @@ int main(int argc, char **argv)
srand(time(NULL));
- set = link_set_create(bsc);
- if (!set) {
- LOGP(DINP, LOGL_ERROR, "Failed to allocate the link.\n");
- return -1;
- }
-
- app = ss7_application_alloc(bsc);
- if (!app) {
- LOGP(DINP, LOGL_ERROR, "Failed to create the SS7 application.\n");
- return -1;
- }
-
- m2ua_set = mtp_link_set_alloc(bsc);
- m2ua_set->dpc = 92;
- m2ua_set->opc = 9;
- m2ua_set->sccp_opc = 9;
- m2ua_set->isup_opc = 9;
- m2ua_set->ni = 3;
- m2ua_set->pcap_fd = bsc->pcap_fd;
- m2ua_set->name = talloc_strdup(m2ua_set, "M2UA");
- m2ua_set->supported_ssn[1] = 1;
- m2ua_set->supported_ssn[7] = 1;
- m2ua_set->supported_ssn[8] = 1;
- m2ua_set->supported_ssn[146] = 1;
- m2ua_set->supported_ssn[254] = 1;
-
cell_vty_init();
- if (vty_read_config_file(config, NULL) < 0) {
- fprintf(stderr, "Failed to read the VTY config.\n");
- return -1;
- }
-
rc = telnet_init(NULL, NULL, 4242);
if (rc < 0)
return rc;
@@ -268,23 +234,40 @@ int main(int argc, char **argv)
return -1;
}
- if (link_init(bsc, set) != 0)
+ /* now bind the the UDP and SCTP port */
+ if (link_global_init(&bsc->udp_data) != 0) {
+ LOGP(DINP, LOGL_ERROR, "Global UDP input init failed.\n");
return -1;
+ }
- bsc->m2ua_trans = sctp_m2ua_transp_create("0.0.0.0", 2904);
+ bsc->m2ua_trans = sctp_m2ua_transp_create(bsc);
if (!bsc->m2ua_trans) {
LOGP(DINP, LOGL_ERROR, "Failed to create SCTP transport.\n");
return -1;
}
- /* setup things */
- lnk = mtp_m2ua_link_create(bsc->m2ua_trans, m2ua_set);
+ if (vty_read_config_file(config, NULL) < 0) {
+ fprintf(stderr, "Failed to read the VTY config.\n");
+ return -1;
+ }
- ss7_application_setup(app, APP_STP,
- SS7_SET_LINKSET, 0,
- SS7_SET_LINKSET, 1);
+ if (link_global_bind(&bsc->udp_data, bsc->udp_src_port) != 0) {
+ LOGP(DINP, LOGL_ERROR, "Global UDP bind failed.\n");
+ return -1;
+ }
- ss7_application_start(app);
+ if (sctp_m2ua_transport_bind(bsc->m2ua_trans, "0.0.0.0", bsc->m2ua_src_port) != 0) {
+ LOGP(DINP, LOGL_ERROR,
+ "Failed to bind on port %d\n", bsc->m2ua_src_port);
+ return -1;
+ }
+
+ /* start all apps */
+ llist_for_each_entry(app, &bsc->apps, entry) {
+ LOGP(DINP, LOGL_NOTICE,
+ "Going to start app %d/%s.\n", app->nr, app->name);
+ ss7_application_start(app);
+ }
while (1) {
bsc_select_main(0);
@@ -293,33 +276,3 @@ int main(int argc, char **argv)
return 0;
}
-/* dummy for links */
-int msc_connection_start(struct msc_connection *conn)
-{
- return 0;
-}
-
-struct msc_connection *msc_connection_num(struct bsc_data *bsc, int num)
-{
- return NULL;
-}
-
-
-void msc_mgcp_reset(struct msc_connection *msc)
-{
-}
-void msc_send_reset(struct msc_connection *bsc)
-{
-}
-void msc_close_connection(struct msc_connection *bsc)
-{
-}
-void app_resources_released(struct ss7_application *ss7)
-{
-}
-void app_clear_connections(struct ss7_application *ss7)
-{
-}
-void app_forward_sccp(struct ss7_application *ss7, struct msgb *_msg, int sls)
-{
-}
diff --git a/src/mtp_layer3.c b/src/mtp_layer3.c
index 08ea323..0ceb7b0 100644
--- a/src/mtp_layer3.c
+++ b/src/mtp_layer3.c
@@ -609,6 +609,9 @@ struct mtp_link_set *mtp_link_set_alloc(struct bsc_data *bsc)
INIT_LLIST_HEAD(&link->links);
link->nr = bsc->num_linksets++;
+ link->sccp_opc = link->isup_opc = -1;
+ link->pcap_fd = bsc->pcap_fd;
+ link->bsc = bsc;
llist_add_tail(&link->entry, &bsc->linksets);
return link;
diff --git a/src/sctp_m2ua.c b/src/sctp_m2ua.c
index 977acad..d0609dd 100644
--- a/src/sctp_m2ua.c
+++ b/src/sctp_m2ua.c
@@ -711,16 +711,33 @@ static int sctp_m2ua_reset(struct mtp_link *_link)
return 0;
}
-struct sctp_m2ua_transport *sctp_m2ua_transp_create(const char *ip, int port)
+struct sctp_m2ua_transport *sctp_m2ua_transp_create(struct bsc_data *bsc)
+{
+ struct sctp_m2ua_transport *trans;
+
+ trans = talloc_zero(bsc, struct sctp_m2ua_transport);
+ if (!trans) {
+ LOGP(DINP, LOGL_ERROR, "Remove the talloc.\n");
+ return NULL;
+ }
+
+ INIT_LLIST_HEAD(&trans->conns);
+ INIT_LLIST_HEAD(&trans->links);
+
+
+ return trans;
+}
+
+int sctp_m2ua_transport_bind(struct sctp_m2ua_transport *trans,
+ const char *ip, int port)
{
int sctp;
struct sockaddr_in addr;
- struct sctp_m2ua_transport *trans;
sctp = socket(PF_INET, SOCK_STREAM, IPPROTO_SCTP);
if (!sctp) {
LOGP(DINP, LOGL_ERROR, "Failed to create socket.\n");
- return NULL;
+ return -1;
}
memset(&addr, 0, sizeof(addr));
@@ -731,25 +748,18 @@ struct sctp_m2ua_transport *sctp_m2ua_transp_create(const char *ip, int port)
if (bind(sctp, (struct sockaddr *) &addr, sizeof(addr)) != 0) {
LOGP(DINP, LOGL_ERROR, "Failed to bind.\n");
close(sctp);
- return NULL;
+ return -2;
}
if (listen(sctp, 1) != 0) {
LOGP(DINP, LOGL_ERROR, "Failed to listen.\n");
close(sctp);
- return NULL;
+ return -3;
}
int on = 1;
setsockopt(sctp, SOL_SCTP, 112, &on, sizeof(on));
- trans = talloc_zero(NULL, struct sctp_m2ua_transport);
- if (!trans) {
- LOGP(DINP, LOGL_ERROR, "Remove the talloc.\n");
- close(sctp);
- return NULL;
- }
-
trans->bsc.fd = sctp;
trans->bsc.data = trans;
trans->bsc.cb = sctp_trans_accept;
@@ -757,33 +767,21 @@ struct sctp_m2ua_transport *sctp_m2ua_transp_create(const char *ip, int port)
if (bsc_register_fd(&trans->bsc) != 0) {
LOGP(DINP, LOGL_ERROR, "Failed to register the fd.\n");
- talloc_free(trans);
close(sctp);
- return NULL;
+ return -4;
}
- INIT_LLIST_HEAD(&trans->conns);
- INIT_LLIST_HEAD(&trans->links);
-
- return trans;
+ return 0;
}
-struct mtp_m2ua_link *mtp_m2ua_link_create(struct sctp_m2ua_transport *trans,
- struct mtp_link_set *set)
+struct mtp_m2ua_link *mtp_m2ua_link_init(struct mtp_link *blnk)
{
- struct mtp_link *blnk;
+ struct sctp_m2ua_transport *trans;
struct mtp_m2ua_link *lnk;
- blnk = mtp_link_alloc(set);
- if (!blnk) {
- LOGP(DINP, LOGL_ERROR, "Failed to allocate.\n");
- return NULL;
- }
-
lnk = talloc_zero(blnk, struct mtp_m2ua_link);
if (!lnk) {
LOGP(DINP, LOGL_ERROR, "Failed to allocate.\n");
- talloc_free(blnk);
return NULL;
}
@@ -793,6 +791,7 @@ struct mtp_m2ua_link *mtp_m2ua_link_create(struct sctp_m2ua_transport *trans,
blnk->type = SS7_LTYPE_M2UA;
/* remember we have a link here */
+ trans = blnk->set->bsc->m2ua_trans;
llist_add_tail(&lnk->entry, &trans->links);
lnk->base->shutdown = sctp_m2ua_reset;
diff --git a/src/snmp_mtp.c b/src/snmp_mtp.c
index 2cdf323..308e6b8 100644
--- a/src/snmp_mtp.c
+++ b/src/snmp_mtp.c
@@ -18,6 +18,7 @@
*
*/
#include <snmp_mtp.h>
+#include <cellmgr_debug.h>
#include <osmocore/talloc.h>
static void add_pdu_var(netsnmp_pdu *pdu, const char *mib_name, int id, const char *value)
@@ -120,7 +121,7 @@ static void snmp_mtp_stop_c7_datalink(struct snmp_mtp_session *session, int link
session->last_do_req = status;
}
-struct snmp_mtp_session *snmp_mtp_session_create(char *host)
+struct snmp_mtp_session *snmp_mtp_session_create()
{
struct snmp_mtp_session *session = talloc_zero(NULL, struct snmp_mtp_session);
if (!session)
@@ -128,21 +129,32 @@ struct snmp_mtp_session *snmp_mtp_session_create(char *host)
init_snmp("cellmgr_ng");
snmp_sess_init(&session->session);
- session->session.peername = host;
session->session.version = SNMP_VERSION_1;
session->session.community = (unsigned char *) "private";
session->session.community_len = strlen((const char *) session->session.community);
session->session.myvoid = session;
+ return session;
+}
+
+int snmp_mtp_peer_name(struct snmp_mtp_session *session, char *host)
+{
+ if (session->ss) {
+ snmp_close(session->ss);
+ session->ss = NULL;
+ }
+
+ session->session.peername = host;
+
session->ss = snmp_open(&session->session);
if (!session->ss) {
snmp_perror("create failure");
snmp_log(LOG_ERR, "Could not connect to the remote.\n");
- talloc_free(session);
- return NULL;
+ LOGP(DINP, LOGL_ERROR, "Failed to open a SNMP session.\n");
+ return -1;
}
- return session;
+ return 0;
}
void snmp_mtp_deactivate(struct snmp_mtp_session *session, int index)
diff --git a/src/ss7_application.c b/src/ss7_application.c
index b3c9036..485aa2e 100644
--- a/src/ss7_application.c
+++ b/src/ss7_application.c
@@ -213,6 +213,7 @@ static int ss7_app_setup_stp(struct ss7_application *app,
app->type = APP_STP;
app->bsc->m2ua_trans->started = 1;
+ app->route_is_set = 1;
return 0;
}
@@ -287,6 +288,7 @@ static int ss7_app_setup_relay(struct ss7_application *app, int type,
app->route_dst.msc = msc;
app->type = type;
+ app->route_is_set = 1;
return 0;
}
@@ -338,6 +340,12 @@ static void start_set(struct ss7_application *app, struct mtp_link_set *set)
int ss7_application_start(struct ss7_application *app)
{
+ if (!app->route_is_set) {
+ LOGP(DINP, LOGL_ERROR,
+ "The routes are not configured on app %d.\n", app->nr);
+ return -1;
+ }
+
start_set(app, app->route_src.set);
start_set(app, app->route_dst.set);
diff --git a/src/vty_interface.c b/src/vty_interface.c
index 6528417..36cdfbb 100644
--- a/src/vty_interface.c
+++ b/src/vty_interface.c
@@ -1,4 +1,4 @@
-/* VTY code for the Cellmgr */
+/* VTY code for the osmo-stp */
/*
* (C) 2010-2011 by Holger Hans Peter Freyther <zecke@selfish.org>
* (C) 2010-2011 by On-Waves
@@ -22,7 +22,11 @@
#include <bsc_data.h>
#include <mtp_pcap.h>
#include <msc_connection.h>
+#include <sctp_m2ua.h>
#include <ss7_application.h>
+#include <ss7_vty.h>
+#include <cellmgr_debug.h>
+#include <snmp_mtp.h>
#include <osmocore/talloc.h>
#include <osmocore/gsm48.h>
@@ -43,288 +47,812 @@
extern struct bsc_data *bsc;
+static enum node_type ss7_go_parent(struct vty *vty)
+{
+ switch (vty->node) {
+ case LINK_NODE:
+ vty->node = LINKSETS_NODE;
+ {
+ struct mtp_link *lnk = vty->index;
+ vty->index = lnk->set;
+ vty->index_sub = &lnk->set->name;
+ }
+ break;
+ case MSC_NODE:
+ case APP_NODE:
+ case LINKSETS_NODE:
+ vty->node = SS7_NODE;
+ vty->index = NULL;
+ vty->index_sub = NULL;
+ break;
+ case SS7_NODE:
+ default:
+ vty->node = CONFIG_NODE;
+ vty->index = NULL;
+ vty->index_sub = NULL;
+ break;
+ }
+
+ return vty->node;
+}
+
+
+DEFUN(node_exit, node_exit_cmd,
+ "exit", "Exit the current node\n")
+{
+ ss7_go_parent(vty);
+ return CMD_SUCCESS;
+}
+
+DEFUN(node_end, node_end_cmd,
+ "end", "End the current mode and change to the enable node\n")
+{
+ switch (vty->node) {
+ case VIEW_NODE:
+ case ENABLE_NODE:
+ break;
+ default:
+ vty_config_unlock(vty);
+ vty->node = ENABLE_NODE;
+ vty->index = NULL;
+ vty->index_sub = NULL;
+ break;
+ }
+ return CMD_SUCCESS;
+}
+
static struct vty_app_info vty_info = {
.name = "Cellmgr-ng",
.version = VERSION,
- .go_parent_cb = NULL,
+ .go_parent_cb = ss7_go_parent,
};
/* vty code */
-enum cellmgr_node {
- CELLMGR_NODE = _LAST_OSMOVTY_NODE,
+
+static struct cmd_node ss7_node = {
+ SS7_NODE,
+ "%s(ss7)#",
+ 1,
+};
+
+static struct cmd_node linkset_node = {
+ LINKSETS_NODE,
+ "%s(linkset)#",
+ 1,
+};
+
+static struct cmd_node link_node = {
+ LINK_NODE,
+ "%s(link)#",
+ 1,
};
-static struct cmd_node cell_node = {
- CELLMGR_NODE,
- "%s(cellmgr)#",
+static struct cmd_node msc_node = {
+ MSC_NODE,
+ "%s(msc)#",
1,
};
-static int config_write_cell(struct vty *vty)
-{
- struct mtp_link_set *set = mtp_link_set_num(bsc, 0);
- struct msc_connection *msc = msc_connection_num(bsc, 0);
- struct ss7_application *app = ss7_application_num(bsc, 0);
-
- vty_out(vty, "cellmgr%s", VTY_NEWLINE);
- vty_out(vty, " mtp dpc %d%s", set->dpc, VTY_NEWLINE);
- vty_out(vty, " mtp opc %d%s", set->opc, VTY_NEWLINE);
- vty_out(vty, " mtp sccp-opc %d%s", set->sccp_opc, VTY_NEWLINE);
- vty_out(vty, " mtp ni %d%s", set->ni, VTY_NEWLINE);
- vty_out(vty, " mtp spare %d%s", set->spare, VTY_NEWLINE);
- vty_out(vty, " mtp sltm once %d%s", set->sltm_once, VTY_NEWLINE);
- if (bsc->udp_ip)
- vty_out(vty, " udp dest ip %s%s", bsc->udp_ip, VTY_NEWLINE);
- vty_out(vty, " udp dest port %d%s", bsc->udp_port, VTY_NEWLINE);
- vty_out(vty, " udp src port %d%s", bsc->src_port, VTY_NEWLINE);
- vty_out(vty, " udp reset %d%s", bsc->udp_reset_timeout, VTY_NEWLINE);
- vty_out(vty, " udp number-links %d%s", bsc->udp_nr_links, VTY_NEWLINE);
- vty_out(vty, " isup pass-through %d%s", app->isup_pass, VTY_NEWLINE);
-
- if (msc) {
- vty_out(vty, " msc ip %s%s", msc->ip, VTY_NEWLINE);
- vty_out(vty, " msc ip-dscp %d%s", msc->dscp, VTY_NEWLINE);
- vty_out(vty, " msc token %s%s", msc->token, VTY_NEWLINE);
+static struct cmd_node app_node = {
+ APP_NODE,
+ "%s(application)#",
+ 1,
+};
+
+static int dummy_write(struct vty *vty)
+{
+ return CMD_SUCCESS;
+}
+
+static int config_write_ss7(struct vty *vty)
+{
+ vty_out(vty, "ss7%s", VTY_NEWLINE);
+ vty_out(vty, " udp src-port %d%s", bsc->udp_src_port, VTY_NEWLINE);
+ vty_out(vty, " m2ua src-port %d%s", bsc->m2ua_src_port, VTY_NEWLINE);
+ return CMD_SUCCESS;
+}
+
+static void write_link(struct vty *vty, struct mtp_link *link)
+{
+ const char *name = link->name ? link->name : "";
+ struct mtp_udp_link *ulnk;
+ struct mtp_m2ua_link *m2ua;
+
+ vty_out(vty, " link %d%s", link->nr, VTY_NEWLINE);
+ vty_out(vty, " description %s%s", name, VTY_NEWLINE);
+
+ switch (link->type) {
+ case SS7_LTYPE_UDP:
+ ulnk = (struct mtp_udp_link *) link->data;
+ vty_out(vty, " ss7-transport udp%s", VTY_NEWLINE);
+ vty_out(vty, " udp dest ip %s%s",
+ inet_ntoa(ulnk->remote.sin_addr), VTY_NEWLINE);
+ vty_out(vty, " udp dest port %d%s",
+ ntohs(ulnk->remote.sin_port), VTY_NEWLINE);
+ vty_out(vty, " udp reset-timeout %d%s",
+ ulnk->reset_timeout, VTY_NEWLINE);
+ vty_out(vty, " udp link-index %d%s",
+ ulnk->link_index, VTY_NEWLINE);
+ break;
+ case SS7_LTYPE_M2UA:
+ m2ua = (struct mtp_m2ua_link *) link->data;
+ vty_out(vty, " ss7-transport m2ua%s", VTY_NEWLINE);
+
+ if (m2ua->as)
+ vty_out(vty, " m2ua application-server %s%s",
+ m2ua->as, VTY_NEWLINE);
+ vty_out(vty, " m2ua link-index %d%s",
+ m2ua->link_index, VTY_NEWLINE);
+ break;
+ case SS7_LTYPE_NONE:
+ break;
+ }
+}
+
+static void write_linkset(struct vty *vty, struct mtp_link_set *set)
+{
+ const char *name = set->name ? set->name : "";
+ struct mtp_link *link;
+ int i;
+
+ vty_out(vty, " linkset %d%s", set->nr, VTY_NEWLINE);
+ vty_out(vty, " description %s%s", name, VTY_NEWLINE);
+ vty_out(vty, " mtp3 dpc %d%s", set->dpc, VTY_NEWLINE);
+ vty_out(vty, " mtp3 opc %d%s", set->opc, VTY_NEWLINE);
+ vty_out(vty, " mtp3 ni %d%s", set->ni, VTY_NEWLINE);
+ vty_out(vty, " mtp3 spare %d%s", set->spare, VTY_NEWLINE);
+ vty_out(vty, " mtp3 sltm-once %d%s", set->sltm_once, VTY_NEWLINE);
+
+ for (i = 0; i < ARRAY_SIZE(set->supported_ssn); ++i) {
+ if (!set->supported_ssn[i])
+ continue;
+ vty_out(vty, " mtp3 ssn %d%s", i, VTY_NEWLINE);
}
+ llist_for_each_entry(link, &set->links, entry)
+ write_link(vty, link);
+}
+
+static int config_write_linkset(struct vty *vty)
+{
+ struct mtp_link_set *set;
+
+ llist_for_each_entry(set, &bsc->linksets, entry)
+ write_linkset(vty, set);
return CMD_SUCCESS;
}
-DEFUN(cfg_cell, cfg_cell_cmd,
- "cellmgr", "Configure the Cellmgr")
+static void write_msc(struct vty *vty, struct msc_connection *msc)
+{
+ const char *name = msc->name ? msc->name : "";
+
+ vty_out(vty, " msc %d%s", msc->nr, VTY_NEWLINE);
+ vty_out(vty, " description %s%s", name, VTY_NEWLINE);
+ vty_out(vty, " ip %s%s", msc->ip, VTY_NEWLINE);
+ vty_out(vty, " token %s%s", msc->token, VTY_NEWLINE);
+ vty_out(vty, " dscp %d%s", msc->dscp, VTY_NEWLINE);
+ vty_out(vty, " timeout ping %d%s", msc->ping_time, VTY_NEWLINE);
+ vty_out(vty, " timeout pong %d%s", msc->pong_time, VTY_NEWLINE);
+ vty_out(vty, " timeout restart %d%s", msc->msc_time, VTY_NEWLINE);
+}
+
+static int config_write_msc(struct vty *vty)
+{
+ struct msc_connection *msc;
+
+ llist_for_each_entry(msc, &bsc->mscs, entry)
+ write_msc(vty, msc);
+ return 0;
+}
+
+static const char *app_type(enum ss7_app_type type)
{
- vty->node = CELLMGR_NODE;
+ switch (type) {
+ case APP_NONE:
+ return "none";
+ case APP_CELLMGR:
+ return "msc";
+ case APP_RELAY:
+ return "relay";
+ case APP_STP:
+ return "stp";
+ default:
+ LOGP(DINP, LOGL_ERROR, "Should no be reached.\n");
+ return "";
+ }
+}
+
+static const char *link_type(enum ss7_set_type type)
+{
+ switch (type) {
+ case SS7_SET_LINKSET:
+ return "linkset";
+ case SS7_SET_MSC:
+ return "msc";
+ default:
+ LOGP(DINP, LOGL_ERROR, "Should no be reached.\n");
+ return "";
+ }
+}
+
+static void write_application(struct vty *vty, struct ss7_application *app)
+{
+ const char *name = app->name ? app->name : "";
+
+ vty_out(vty, " application %d%s", app->nr, VTY_NEWLINE);
+ vty_out(vty, " description %s%s", name, VTY_NEWLINE);
+ vty_out(vty, " type %s%s", app_type(app->type), VTY_NEWLINE);
+
+ if (app->type == APP_STP)
+ vty_out(vty, " isup-pass-through %d%s", app->isup_pass, VTY_NEWLINE);
+
+ if (app->route_is_set) {
+ vty_out(vty, " route %s %d %s %d%s",
+ link_type(app->route_src.type), app->route_src.nr,
+ link_type(app->route_dst.type), app->route_dst.nr,
+ VTY_NEWLINE);
+ }
+}
+
+static int config_write_app(struct vty *vty)
+{
+ struct ss7_application *app;
+
+ llist_for_each_entry(app, &bsc->apps, entry)
+ write_application(vty, app);
+
return CMD_SUCCESS;
}
-DEFUN(cfg_net_dpc, cfg_net_dpc_cmd,
- "mtp dpc DPC_NR",
- "Set the DPC to be used.")
+DEFUN(cfg_ss7, cfg_ss7_cmd,
+ "ss7", "Configure the application\n")
{
- struct mtp_link_set *set = mtp_link_set_num(bsc, 0);
- set->dpc = atoi(argv[0]);
+ vty->node = SS7_NODE;
return CMD_SUCCESS;
}
-DEFUN(cfg_net_opc, cfg_net_opc_cmd,
- "mtp opc OPC_NR",
- "Set the OPC to be used.")
+DEFUN(cfg_ss7_udp_src_port, cfg_ss7_udp_src_port_cmd,
+ "udp src-port <1-65535>",
+ "UDP related commands\n"
+ "Source port for SS7 via UDP transport\n"
+ "Port to bind to\n")
{
- struct mtp_link_set *set = mtp_link_set_num(bsc, 0);
- set->opc = atoi(argv[0]);
+ bsc->udp_src_port = atoi(argv[0]);
+ return CMD_SUCCESS;
+}
+
+DEFUN(cfg_ss7_m2ua_src_port, cfg_ss7_m2ua_src_port_cmd,
+ "m2ua src-port <1-65535>",
+ "M2UA related commands\n"
+ "Source port for SS7 via M2UA\n"
+ "Port to bind to\n")
+{
+ bsc->m2ua_src_port = atoi(argv[0]);
+ return CMD_SUCCESS;
+}
+
+DEFUN(cfg_ss7_linkset, cfg_ss7_linkset_cmd,
+ "linkset <0-100>",
+ "Linkset commands\n" "Linkset number\n")
+{
+ struct mtp_link_set *set;
+ int nr;
+
+ nr = atoi(argv[0]);
+ if (nr > bsc->num_linksets) {
+ vty_out(vty, "%% The next unused Linkset number is %u%s",
+ bsc->num_linksets, VTY_NEWLINE);
+ return CMD_WARNING;
+ } else if (nr == bsc->num_linksets) {
+ set = mtp_link_set_alloc(bsc);
+ } else
+ set = mtp_link_set_num(bsc, nr);
+
+ if (!set) {
+ vty_out(vty, "%% Unable to allocate Linkset %u%s",
+ nr, VTY_NEWLINE);
+ return CMD_WARNING;
+ }
+
+ vty->node = LINKSETS_NODE;
+ vty->index = set;
+ vty->index_sub = &set->name;
return CMD_SUCCESS;
}
-DEFUN(cfg_net_sccp_opc, cfg_net_sccp_opc_cmd,
- "mtp sccp-opc OPC_NR",
- "Set the SCCP OPC to be used.")
+DEFUN(cfg_linkset_mtp3_dpc, cfg_linkset_mtp3_dpc_cmd,
+ "mtp3 dpc <0-255>",
+ "MTP Level3\n" "Destination Point Code\n" "Point Code\n")
{
- struct mtp_link_set *set = mtp_link_set_num(bsc, 0);
- set->sccp_opc = atoi(argv[0]);
+ struct mtp_link_set *set = vty->index;
+ set->dpc = atoi(argv[0]);
return CMD_SUCCESS;
}
-DEFUN(cfg_net_mtp_ni, cfg_net_mtp_ni_cmd,
- "mtp ni NR",
- "Set the MTP NI to be used.\n" "NR")
+DEFUN(cfg_linkset_mtp3_opc, cfg_linkset_mtp3_opc_cmd,
+ "mtp3 opc <0-255>",
+ "MTP Level3\n" "Originating Point Code\n" "Point Code\n")
{
- struct mtp_link_set *set = mtp_link_set_num(bsc, 0);
+ struct mtp_link_set *set = vty->index;
+ set->opc = atoi(argv[0]);
+ return CMD_SUCCESS;
+}
+
+DEFUN(cfg_linkset_mtp3_ni, cfg_linkset_mtp3_ni_cmd,
+ "mtp3 ni <0-3>",
+ "MTP Level3\n" "NI for the address\n" "NI\n")
+{
+ struct mtp_link_set *set = vty->index;
set->ni = atoi(argv[0]);
return CMD_SUCCESS;
}
-DEFUN(cfg_net_mtp_spare, cfg_net_mtp_spare_cmd,
- "mtp spare NR",
- "Set the MTP Spare to be used.\n" "NR")
+DEFUN(cfg_linkset_mtp3_spare, cfg_linkset_mtp3_spare_cmd,
+ "mtp3 spare <0-3>",
+ "MTP Level3\n" "Spare for the address\n" "Spare\n")
{
- struct mtp_link_set *set = mtp_link_set_num(bsc, 0);
+ struct mtp_link_set *set = vty->index;
set->spare = atoi(argv[0]);
return CMD_SUCCESS;
}
+DEFUN(cfg_linkset_mtp3_ssn, cfg_linkset_mtp3_ssn_cmd,
+ "mtp3 ssn <0-255>",
+ "MTP Level3\n" "SSN supported\n" "SSN\n")
+{
+ struct mtp_link_set *set = vty->index;
+ set->supported_ssn[atoi(argv[0])] = 1;
+ return CMD_SUCCESS;
+}
+
+DEFUN(cfg_linkset_no_mtp3_ssn, cfg_linkset_no_mtp3_ssn_cmd,
+ "no mtp3 ssn <0-255>",
+ "MTP Level3\n" "SSN supported\n" "SSN\n")
+{
+ struct mtp_link_set *set = vty->index;
+ set->supported_ssn[atoi(argv[0])] = 0;
+ return CMD_SUCCESS;
+}
+
+DEFUN(cfg_linkset_sltm_once, cfg_linkset_sltm_once_cmd,
+ "mtp3 sltm-once (0|1)",
+ "MTP Level3\n" "Test the link once\n" "Continous testing\n" "Test once\n")
+{
+ struct mtp_link_set *set = vty->index;
+ set->sltm_once = !!atoi(argv[0]);
+
+ return CMD_SUCCESS;
+}
+
+DEFUN(cfg_linkset_link, cfg_linkset_link_cmd,
+ "link <0-100>",
+ "Link\n" "Link number\n")
+{
+ struct mtp_link_set *set = vty->index;
+
+ struct mtp_link *lnk;
+ int nr;
+
+ nr = atoi(argv[0]);
+ if (nr > set->nr_links) {
+ vty_out(vty, "%% The next unused Link number is %u%s",
+ set->nr_links, VTY_NEWLINE);
+ return CMD_WARNING;
+ } else if (nr == set->nr_links) {
+ lnk = mtp_link_alloc(set);
+ } else
+ lnk = mtp_link_num(set, nr);
+
+ if (!set) {
+ vty_out(vty, "%% Unable to allocate Link %u%s",
+ nr, VTY_NEWLINE);
+ return CMD_WARNING;
+ }
+
+ vty->node = LINK_NODE;
+ vty->index = lnk;
+ vty->index_sub = &lnk->name;
+ return CMD_SUCCESS;
+}
-DEFUN(cfg_udp_dst_ip, cfg_udp_dst_ip_cmd,
- "udp dest ip IP",
- "Set the IP when UDP mode is supposed to be used.")
+DEFUN(cfg_link_ss7_transport, cfg_link_ss7_transport_cmd,
+ "ss7-transport (none|udp|m2ua)",
+ "SS7 transport for the link\n"
+ "No transport\n" "MTP over UDP\n" "SCTP M2UA\n")
+{
+ int wanted = SS7_LTYPE_NONE;
+ struct mtp_link *link;
+
+ link = vty->index;
+
+ if (strcmp("udp", argv[0]) == 0)
+ wanted = SS7_LTYPE_UDP;
+ else if (strcmp("m2ua", argv[0]) == 0)
+ wanted = SS7_LTYPE_M2UA;
+
+ if (link->type != wanted && link->type != SS7_LTYPE_NONE) {
+ vty_out(vty, "%%Can not change the type of a link.\n");
+ return CMD_WARNING;
+ }
+
+ switch (wanted) {
+ case SS7_LTYPE_UDP:
+ link->data = mtp_udp_link_init(link);
+ break;
+ case SS7_LTYPE_M2UA:
+ link->data = mtp_m2ua_link_init(link);
+ break;
+ case SS7_LTYPE_NONE:
+ /* nothing */
+ break;
+ }
+
+ if (!link->data) {
+ vty_out(vty, "Failed to allocate the link type.%s", VTY_NEWLINE);
+ return CMD_WARNING;
+ }
+
+ return CMD_SUCCESS;
+}
+
+DEFUN(cfg_link_udp_dest_ip, cfg_link_udp_dest_ip_cmd,
+ "udp dest ip HOST_NAME",
+ "UDP Transport\n" "IP\n" "Hostname\n")
{
struct hostent *hosts;
- struct in_addr *addr;
- hosts = gethostbyname(argv[0]);
+ struct mtp_link *link = vty->index;
+ struct mtp_udp_link *ulnk;
+
+ if (link->type != SS7_LTYPE_UDP) {
+ vty_out(vty, "%%This only applies to UDP links.%s", VTY_NEWLINE);
+ return CMD_WARNING;
+ }
+
+ ulnk = link->data;
+
+ if (ulnk->dest)
+ talloc_free(ulnk->dest);
+ ulnk->dest = talloc_strdup(ulnk, argv[0]);
+
+ hosts = gethostbyname(ulnk->dest);
if (!hosts || hosts->h_length < 1 || hosts->h_addrtype != AF_INET) {
vty_out(vty, "Failed to resolve '%s'%s", argv[0], VTY_NEWLINE);
return CMD_WARNING;
}
+ ulnk->remote.sin_addr = * (struct in_addr *) hosts->h_addr_list[0];
+
+ if (snmp_mtp_peer_name(ulnk->session, ulnk->dest) != 0) {
+ vty_out(vty, "%%Failed to open SNMP port on link %d.%s",
+ link->nr, VTY_NEWLINE);
+ return CMD_WARNING;
+ }
- addr = (struct in_addr *) hosts->h_addr_list[0];
- bsc->udp_ip = talloc_strdup(NULL, inet_ntoa(*addr));
return CMD_SUCCESS;
}
-DEFUN(cfg_udp_dst_port, cfg_udp_dst_port_cmd,
- "udp dest port PORT_NR",
- "If UDP mode is used specify the UDP dest port")
+DEFUN(cfg_link_udp_dest_port, cfg_link_udp_dest_port_cmd,
+ "udp dest port <1-65535>",
+ "UDP Transport\n" "Set the port number\n" "Port\n")
{
- bsc->udp_port = atoi(argv[0]);
+ struct mtp_link *link = vty->index;
+ struct mtp_udp_link *ulnk;
+
+ if (link->type != SS7_LTYPE_UDP) {
+ vty_out(vty, "%%This only applies to UDP links.%s", VTY_NEWLINE);
+ return CMD_WARNING;
+ }
+
+ ulnk = link->data;
+ ulnk->remote.sin_port = htons(atoi(argv[0]));
return CMD_SUCCESS;
}
-DEFUN(cfg_udp_src_port, cfg_udp_src_port_cmd,
- "udp src port PORT_NR",
- "Set the UDP source port to be used.")
+DEFUN(cfg_link_udp_reset, cfg_link_udp_reset_cmd,
+ "udp reset-timeout <1-65535>",
+ "UDP Transport\n" "Reset timeout after a failure\n" "Seconds\n")
{
- bsc->src_port = atoi(argv[0]);
+ struct mtp_link *link = vty->index;
+ struct mtp_udp_link *ulnk;
+
+ if (link->type != SS7_LTYPE_UDP) {
+ vty_out(vty, "%%This only applies to UDP links.%s", VTY_NEWLINE);
+ return CMD_WARNING;
+ }
+
+ ulnk = link->data;
+ ulnk->reset_timeout = atoi(argv[0]);
return CMD_SUCCESS;
}
-DEFUN(cfg_udp_reset, cfg_udp_reset_cmd,
- "udp reset TIMEOUT",
- "Set the timeout to take the link down")
+DEFUN(cfg_link_udp_link_index, cfg_link_udp_link_index_cmd,
+ "udp link-index <0-65535>",
+ "UDP Transport\n" "Link index\n" "Index\n")
{
- bsc->udp_reset_timeout = atoi(argv[0]);
+ struct mtp_link *link = vty->index;
+ struct mtp_udp_link *ulnk;
+
+ if (link->type != SS7_LTYPE_UDP) {
+ vty_out(vty, "%%This only applies to UDP links.%s", VTY_NEWLINE);
+ return CMD_WARNING;
+ }
+
+ ulnk = link->data;
+ ulnk->link_index = atoi(argv[0]);
return CMD_SUCCESS;
}
-DEFUN(cfg_udp_nr_links, cfg_udp_nr_links_cmd,
- "udp number-links <1-32>",
- "Set the number of links to use\n")
+DEFUN(cfg_link_m2ua_as, cfg_link_m2ua_as_cmd,
+ "m2ua application-server NAME",
+ "M2UA Transport\n" "Application Server Name\n" "Name\n")
{
- bsc->udp_nr_links = atoi(argv[0]);
+ struct mtp_link *link = vty->index;
+ struct mtp_m2ua_link *m2ua;
+
+ if (link->type != SS7_LTYPE_M2UA) {
+ vty_out(vty, "%%This only applies to M2UA links.%s", VTY_NEWLINE);
+ return CMD_WARNING;
+ }
+
+ m2ua = link->data;
+ if (m2ua->as)
+ talloc_free(m2ua->as);
+ m2ua->as = talloc_strdup(m2ua, argv[0]);
return CMD_SUCCESS;
}
-DEFUN(cfg_sltm_once, cfg_sltm_once_cmd,
- "mtp sltm once (0|1)",
- "Send SLTMs until the link is established.")
+DEFUN(cfg_link_m2ua_link_index, cfg_link_m2ua_link_index_cmd,
+ "m2ua link-index <0-65535>",
+ "M2UA Transport\n" "Link index\n" "Index\n")
{
- struct mtp_link_set *set = mtp_link_set_num(bsc, 0);
- set->sltm_once = !!atoi(argv[0]);
+ struct mtp_link *link = vty->index;
+ struct mtp_m2ua_link *m2ua;
+
+ if (link->type != SS7_LTYPE_M2UA) {
+ vty_out(vty, "%%This only applies to M2UA links.%s", VTY_NEWLINE);
+ return CMD_WARNING;
+ }
+
+ m2ua = link->data;
+ m2ua->link_index = atoi(argv[0]);
return CMD_SUCCESS;
}
-DEFUN(cfg_msc_ip, cfg_msc_ip_cmd,
- "msc ip IP",
- "Set the MSC IP")
+DEFUN(cfg_ss7_msc, cfg_ss7_msc_cmd,
+ "msc <0-100>",
+ "MSC Connection\n" "MSC Number\n")
{
- struct hostent *hosts;
- struct in_addr *addr;
- struct msc_connection *msc = msc_connection_num(bsc, 0);
+ struct msc_connection *msc;
+ int nr;
+
+ nr = atoi(argv[0]);
+ if (nr > bsc->num_mscs) {
+ vty_out(vty, "%% The next unused MSC number is %u%s",
+ bsc->num_mscs, VTY_NEWLINE);
+ return CMD_WARNING;
+ } else if (nr == bsc->num_mscs) {
+ msc = msc_connection_create(bsc, 1);
+ } else
+ msc = msc_connection_num(bsc, nr);
if (!msc) {
- vty_out(vty, "%%No MSC Connection defined in this app.%s", VTY_NEWLINE);
+ vty_out(vty, "%% Unable to allocate MSC %u%s",
+ nr, VTY_NEWLINE);
return CMD_WARNING;
}
+ vty->node = MSC_NODE;
+ vty->index = msc;
+ vty->index_sub = &msc->name;
+ return CMD_SUCCESS;
+}
+
+DEFUN(cfg_msc_ip, cfg_msc_ip_cmd,
+ "ip ADDR",
+ "IP Address of the MSC\n" "Address\n")
+{
+ struct hostent *hosts;
+ struct msc_connection *msc;
+
+ msc = vty->index;
hosts = gethostbyname(argv[0]);
if (!hosts || hosts->h_length < 1 || hosts->h_addrtype != AF_INET) {
vty_out(vty, "Failed to resolve '%s'%s", argv[0], VTY_NEWLINE);
return CMD_WARNING;
}
- addr = (struct in_addr *) hosts->h_addr_list[0];
-
if (msc->ip)
talloc_free(msc->ip);
- msc->ip = talloc_strdup(msc, inet_ntoa(*addr));
+
+ msc->ip = talloc_strdup(msc,
+ inet_ntoa(*((struct in_addr *) hosts->h_addr_list[0])));
return CMD_SUCCESS;
}
-DEFUN(cfg_msc_ip_dscp, cfg_msc_ip_dscp_cmd,
- "msc ip-dscp <0-255>",
- "Set the IP DSCP on the A-link\n"
- "Set the DSCP in IP packets to the MSC")
+DEFUN(cfg_msc_token, cfg_msc_token_cmd,
+ "token TOKEN",
+ "Token for the MSC\n" "The token\n")
{
- struct msc_connection *msc = msc_connection_num(bsc, 0);
+ struct msc_connection *msc = vty->index;
- if (!msc) {
- vty_out(vty, "%%No MSC Connection defined in this app.%s", VTY_NEWLINE);
- return CMD_WARNING;
- }
+ if (msc->token)
+ talloc_free(msc->token);
+ msc->token = talloc_strdup(msc, argv[0]);
+ return CMD_SUCCESS;
+}
+DEFUN(cfg_msc_dscp, cfg_msc_dscp_cmd,
+ "dscp <0-255>",
+ "DSCP for the IP Connection\n" "Nr\n")
+{
+ struct msc_connection *msc = vty->index;
msc->dscp = atoi(argv[0]);
return CMD_SUCCESS;
}
-ALIAS_DEPRECATED(cfg_msc_ip_dscp, cfg_msc_ip_tos_cmd,
- "msc ip-tos <0-255>",
- "Set the IP DSCP on the A-link\n"
- "Set the DSCP in IP packets to the MSC")
+DEFUN(cfg_msc_timeout_ping, cfg_msc_timeout_ping_cmd,
+ "timeout ping <1-65535>",
+ "Timeout commands\n" "Time between pings\n" "Seconds\n")
+{
+ struct msc_connection *msc = vty->index;
+ msc->ping_time = atoi(argv[0]);
+ return CMD_SUCCESS;
+}
-DEFUN(cfg_msc_token, cfg_msc_token_cmd,
- "msc token TOKEN",
- "Set the Token to be used for the MSC")
+DEFUN(cfg_msc_timeout_pong, cfg_msc_timeout_pong_cmd,
+ "timeout pong <1-65535>",
+ "Timeout commands\n" "Time between pongs\n" "Seconds\n")
+{
+ struct msc_connection *msc = vty->index;
+ msc->pong_time = atoi(argv[0]);
+ return CMD_SUCCESS;
+}
+
+DEFUN(cfg_msc_timeout_restart, cfg_msc_timeout_restart_cmd,
+ "timeout restart <1-65535>",
+ "Timeout commands\n" "Time between restarts\n" "Seconds\n")
{
- struct msc_connection *msc = msc_connection_num(bsc, 0);
+ struct msc_connection *msc = vty->index;
+ msc->msc_time = atoi(argv[0]);
+ return CMD_SUCCESS;
+}
- if (!msc) {
- vty_out(vty, "%%No MSC Connection defined in this app.%s", VTY_NEWLINE);
+DEFUN(cfg_ss7_app, cfg_ss7_app_cmd,
+ "application <0-100>",
+ "Application Commands\n" "Number\n")
+{
+ struct ss7_application *app;
+ int nr;
+
+ nr = atoi(argv[0]);
+ if (nr > bsc->num_apps) {
+ vty_out(vty, "%% The next unused Application number is %u%s",
+ bsc->num_apps, VTY_NEWLINE);
+ return CMD_WARNING;
+ } else if (nr == bsc->num_apps) {
+ app = ss7_application_alloc(bsc);
+ } else
+ app = ss7_application_num(bsc, nr);
+
+ if (!app) {
+ vty_out(vty, "%% Unable to allocate Application %u%s",
+ nr, VTY_NEWLINE);
return CMD_WARNING;
}
- if (msc->token)
- talloc_free(msc->token);
- msc->token = talloc_strdup(msc, argv[0]);
+ vty->node = APP_NODE;
+ vty->index = app;
+ vty->index_sub = &app->name;
return CMD_SUCCESS;
}
-DEFUN(cfg_ping_time, cfg_ping_time_cmd,
- "timeout ping NR",
- "Set the PING interval. Negative to disable it")
+DEFUN(cfg_app_type, cfg_app_type_cmd,
+ "type (none|stp|relay|msc)",
+ "Type of Application\n"
+ "No type\n" "Signalling Transfer Point\n"
+ "Relay SCCP/ISUP messages\n" "MSC connector with state\n")
{
- struct msc_connection *msc = msc_connection_num(bsc, 0);
+ enum ss7_app_type type;
+ struct ss7_application *app = vty->index;
+
+ switch (argv[0][0]) {
+ case 'm':
+ type = APP_CELLMGR;
+ break;
+ case 'r':
+ type = APP_RELAY;
+ break;
+ case 's':
+ type = APP_STP;
+ break;
+ default:
+ case 'n':
+ type = APP_NONE;
+ break;
+ }
- if (!msc) {
- vty_out(vty, "%%No MSC Connection defined in this app.%s", VTY_NEWLINE);
+ if (app->type != APP_NONE && app->type != type) {
+ vty_out(vty, "The type can not be changed at runtime on app %d.%s",
+ app->nr, VTY_NEWLINE);
return CMD_WARNING;
}
- msc->ping_time = atoi(argv[0]);
+ app->type = type;
return CMD_SUCCESS;
}
-DEFUN(cfg_pong_time, cfg_pong_time_cmd,
- "timeout pong NR",
- "Set the PING interval. Negative to disable it")
+DEFUN(cfg_app_isup_pass, cfg_app_isup_pass_cmd,
+ "isup-pass-through (0|1)",
+ "Pass all ISUP messages\n" "Handle some ISUP locally\n" "Pass all messages\n")
{
- struct msc_connection *msc = msc_connection_num(bsc, 0);
+ struct ss7_application *app = vty->index;
- if (!msc) {
- vty_out(vty, "%%No MSC Connection defined in this app.%s", VTY_NEWLINE);
+ if (app->type != APP_STP) {
+ vty_out(vty, "%%Need to use the 'stp' app for this option on app %d.%s",
+ app->nr, VTY_NEWLINE);
return CMD_WARNING;
}
- msc->pong_time = atoi(argv[0]);
+ ss7_application_pass_isup(app, atoi(argv[0]));
return CMD_SUCCESS;
}
-DEFUN(cfg_msc_time, cfg_msc_time_cmd,
- "timeout msc NR",
- "Set the MSC connect timeout")
+DEFUN(cfg_app_route, cfg_app_route_cmd,
+ "route linkset <0-100> msc <0-100>",
+ "Routing commands\n" "Source Linkset\n" "Linkset Nr\n"
+ "Dest MSC\n" "MSC Nr\n")
{
- struct msc_connection *msc = msc_connection_num(bsc, 0);
+ struct ss7_application *app = vty->index;
- if (!msc) {
- vty_out(vty, "%%No MSC Connection defined in this app.%s", VTY_NEWLINE);
+ if (app->type != APP_CELLMGR && app->type != APP_RELAY) {
+ vty_out(vty, "The app type needs to be 'relay' or 'msc'.%s", VTY_NEWLINE);
+ return CMD_WARNING;
+ }
+
+ if (ss7_application_setup(app, app->type,
+ SS7_SET_LINKSET, atoi(argv[0]),
+ SS7_SET_MSC, atoi(argv[1])) != 0) {
+ vty_out(vty, "Failed to route linkset %d to msc %d.%s",
+ atoi(argv[0]), atoi(argv[1]), VTY_NEWLINE);
return CMD_WARNING;
}
- msc->msc_time = atoi(argv[0]);
return CMD_SUCCESS;
}
-DEFUN(cfg_isup_pass, cfg_isup_pass_cmd,
- "isup pass-through (0|1)",
- "ISUP related functionality\n"
- "Pass through all ISUP messages directly\n"
- "Handle some messages locally\n" "Pass through everything\n")
+DEFUN(cfg_app_route_ls, cfg_app_route_ls_cmd,
+ "route linkset <0-100> linkset <0-100>",
+ "Routing commands\n" "Source Linkset\n" "Linkset Nr\n"
+ "Dest Linkset\n" "Linkset Nr\n" )
{
- struct ss7_application *app = ss7_application_num(bsc, 0);
- ss7_application_pass_isup(app, atoi(argv[0]));
+ struct ss7_application *app = vty->index;
+
+ if (app->type != APP_STP) {
+ vty_out(vty, "The app type needs to be 'stp'.%s", VTY_NEWLINE);
+ return CMD_WARNING;
+ }
+
+ if (ss7_application_setup(app, app->type,
+ SS7_SET_LINKSET, atoi(argv[0]),
+ SS7_SET_LINKSET, atoi(argv[1])) != 0) {
+ vty_out(vty, "Failed to route linkset %d to linkset %d.%s",
+ atoi(argv[0]), atoi(argv[1]), VTY_NEWLINE);
+ return CMD_WARNING;
+ }
return CMD_SUCCESS;
}
+static void install_defaults(int node)
+{
+ install_default(node);
+ install_element(node, &node_exit_cmd);
+ install_element(node, &node_end_cmd);
+ install_element(node, &cfg_description_cmd);
+ install_element(node, &cfg_no_description_cmd);
+}
+
extern void cell_vty_init_cmds(void);
void cell_vty_init(void)
{
@@ -332,28 +860,51 @@ void cell_vty_init(void)
vty_init(&vty_info);
logging_vty_add_cmds();
- install_element(CONFIG_NODE, &cfg_cell_cmd);
- install_node(&cell_node, config_write_cell);
-
- install_element(CELLMGR_NODE, &cfg_net_dpc_cmd);
- install_element(CELLMGR_NODE, &cfg_net_opc_cmd);
- install_element(CELLMGR_NODE, &cfg_net_sccp_opc_cmd);
- install_element(CELLMGR_NODE, &cfg_net_mtp_ni_cmd);
- install_element(CELLMGR_NODE, &cfg_net_mtp_spare_cmd);
- install_element(CELLMGR_NODE, &cfg_udp_dst_ip_cmd);
- install_element(CELLMGR_NODE, &cfg_udp_dst_port_cmd);
- install_element(CELLMGR_NODE, &cfg_udp_src_port_cmd);
- install_element(CELLMGR_NODE, &cfg_udp_reset_cmd);
- install_element(CELLMGR_NODE, &cfg_udp_nr_links_cmd);
- install_element(CELLMGR_NODE, &cfg_sltm_once_cmd);
- install_element(CELLMGR_NODE, &cfg_msc_ip_cmd);
- install_element(CELLMGR_NODE, &cfg_msc_token_cmd);
- install_element(CELLMGR_NODE, &cfg_msc_ip_dscp_cmd);
- install_element(CELLMGR_NODE, &cfg_msc_ip_tos_cmd);
- install_element(CELLMGR_NODE, &cfg_ping_time_cmd);
- install_element(CELLMGR_NODE, &cfg_pong_time_cmd);
- install_element(CELLMGR_NODE, &cfg_msc_time_cmd);
- install_element(CELLMGR_NODE, &cfg_isup_pass_cmd);
+ install_element(CONFIG_NODE, &cfg_ss7_cmd);
+ install_node(&ss7_node, config_write_ss7);
+ install_defaults(SS7_NODE);
+ install_element(SS7_NODE, &cfg_ss7_udp_src_port_cmd);
+ install_element(SS7_NODE, &cfg_ss7_m2ua_src_port_cmd);
+
+ install_element(SS7_NODE, &cfg_ss7_linkset_cmd);
+ install_node(&linkset_node, config_write_linkset);
+ install_defaults(LINKSETS_NODE);
+ install_element(LINKSETS_NODE, &cfg_linkset_mtp3_dpc_cmd);
+ install_element(LINKSETS_NODE, &cfg_linkset_mtp3_opc_cmd);
+ install_element(LINKSETS_NODE, &cfg_linkset_mtp3_ni_cmd);
+ install_element(LINKSETS_NODE, &cfg_linkset_mtp3_spare_cmd);
+ install_element(LINKSETS_NODE, &cfg_linkset_mtp3_ssn_cmd);
+ install_element(LINKSETS_NODE, &cfg_linkset_no_mtp3_ssn_cmd);
+ install_element(LINKSETS_NODE, &cfg_linkset_sltm_once_cmd);
+
+ install_element(LINKSETS_NODE, &cfg_linkset_link_cmd);
+ install_node(&link_node, dummy_write);
+ install_defaults(LINK_NODE);
+ install_element(LINK_NODE, &cfg_link_ss7_transport_cmd);
+ install_element(LINK_NODE, &cfg_link_udp_dest_ip_cmd);
+ install_element(LINK_NODE, &cfg_link_udp_dest_port_cmd);
+ install_element(LINK_NODE, &cfg_link_udp_reset_cmd);
+ install_element(LINK_NODE, &cfg_link_udp_link_index_cmd);
+ install_element(LINK_NODE, &cfg_link_m2ua_as_cmd);
+ install_element(LINK_NODE, &cfg_link_m2ua_link_index_cmd);
+
+ install_element(SS7_NODE, &cfg_ss7_msc_cmd);
+ install_node(&msc_node, config_write_msc);
+ install_defaults(MSC_NODE);
+ install_element(MSC_NODE, &cfg_msc_ip_cmd);
+ install_element(MSC_NODE, &cfg_msc_token_cmd);
+ install_element(MSC_NODE, &cfg_msc_dscp_cmd);
+ install_element(MSC_NODE, &cfg_msc_timeout_ping_cmd);
+ install_element(MSC_NODE, &cfg_msc_timeout_pong_cmd);
+ install_element(MSC_NODE, &cfg_msc_timeout_restart_cmd);
+
+ install_element(SS7_NODE, &cfg_ss7_app_cmd);
+ install_node(&app_node, config_write_app);
+ install_defaults(APP_NODE);
+ install_element(APP_NODE, &cfg_app_type_cmd);
+ install_element(APP_NODE, &cfg_app_isup_pass_cmd);
+ install_element(APP_NODE, &cfg_app_route_cmd);
+ install_element(APP_NODE, &cfg_app_route_ls_cmd);
cell_vty_init_cmds();
}
diff --git a/src/vty_interface_cmds.c b/src/vty_interface_cmds.c
index e3c82cb..988444b 100644
--- a/src/vty_interface_cmds.c
+++ b/src/vty_interface_cmds.c
@@ -65,13 +65,14 @@ static void dump_state(struct vty *vty, struct mtp_link_set *set)
{
struct mtp_link *link;
- if (!set) {
- vty_out(vty, "LinkSet for %s is not configured.%s", set->name, VTY_NEWLINE);
+ if (!set->app) {
+ vty_out(vty, "LinkSet %d not assigned to an application.%s",
+ set->nr, VTY_NEWLINE);
return;
}
- vty_out(vty, "LinkSet for %s is %s, remote sccp is %s.%s",
- set->name,
+ vty_out(vty, "LinkSet for %d/%s is %s, remote sccp is %s.%s",
+ set->nr, set->name,
set->available == 0 ? "not available" : "available",
set->sccp_up == 0? "not established" : "established",
VTY_NEWLINE);
@@ -200,6 +201,10 @@ DEFUN(pcap_set_stop, pcap_set_stop_cmd,
vty_out(vty, "Unknown Linkset nr %d.%s", set_no, VTY_NEWLINE); \
return CMD_WARNING; \
} \
+ if (!set->app) { \
+ vty_out(vty, "Linkset nr %d has no application.%s", \
+ set_no, VTY_NEWLINE); \
+ } \
link = mtp_link_num(set, nr); \
if (!link) { \
vty_out(vty, "Can not find link %d.%s", nr, VTY_NEWLINE); \
diff --git a/src/vty_interface_legacy.c b/src/vty_interface_legacy.c
new file mode 100644
index 0000000..59f3852
--- /dev/null
+++ b/src/vty_interface_legacy.c
@@ -0,0 +1,358 @@
+/* VTY code for the Cellmgr */
+/*
+ * (C) 2010-2011 by Holger Hans Peter Freyther <zecke@selfish.org>
+ * (C) 2010-2011 by On-Waves
+ * All Rights Reserved
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Affero General Public License as published by
+ * the Free Software Foundation, either version 3 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 Affero General Public License for more details.
+ *
+ * You should have received a copy of the GNU Affero General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ *
+ */
+
+#include <bsc_data.h>
+#include <mtp_pcap.h>
+#include <msc_connection.h>
+#include <ss7_application.h>
+#include <ss7_vty.h>
+
+#include <osmocore/talloc.h>
+#include <osmocore/gsm48.h>
+
+#include <osmocom/vty/command.h>
+#include <osmocom/vty/logging.h>
+#include <osmocom/vty/vty.h>
+
+#include <unistd.h>
+#include <netdb.h>
+
+#undef PACKAGE_NAME
+#undef PACKAGE_VERSION
+#undef PACKAGE_BUGREPORT
+#undef PACKAGE_TARNAME
+#undef PACKAGE_STRING
+#include <cellmgr_config.h>
+
+extern struct bsc_data *bsc;
+
+static struct vty_app_info vty_info = {
+ .name = "Cellmgr-ng",
+ .version = VERSION,
+ .go_parent_cb = NULL,
+};
+
+/* vty code */
+static struct cmd_node cell_node = {
+ CELLMGR_NODE,
+ "%s(cellmgr)#",
+ 1,
+};
+
+static int config_write_cell(struct vty *vty)
+{
+ struct mtp_link_set *set = mtp_link_set_num(bsc, 0);
+ struct msc_connection *msc = msc_connection_num(bsc, 0);
+ struct ss7_application *app = ss7_application_num(bsc, 0);
+
+ vty_out(vty, "cellmgr%s", VTY_NEWLINE);
+ vty_out(vty, " mtp dpc %d%s", set->dpc, VTY_NEWLINE);
+ vty_out(vty, " mtp opc %d%s", set->opc, VTY_NEWLINE);
+ vty_out(vty, " mtp sccp-opc %d%s", set->sccp_opc, VTY_NEWLINE);
+ vty_out(vty, " mtp ni %d%s", set->ni, VTY_NEWLINE);
+ vty_out(vty, " mtp spare %d%s", set->spare, VTY_NEWLINE);
+ vty_out(vty, " mtp sltm once %d%s", set->sltm_once, VTY_NEWLINE);
+ if (bsc->udp_ip)
+ vty_out(vty, " udp dest ip %s%s", bsc->udp_ip, VTY_NEWLINE);
+ vty_out(vty, " udp dest port %d%s", bsc->udp_port, VTY_NEWLINE);
+ vty_out(vty, " udp src port %d%s", bsc->udp_src_port, VTY_NEWLINE);
+ vty_out(vty, " udp reset %d%s", bsc->udp_reset_timeout, VTY_NEWLINE);
+ vty_out(vty, " udp number-links %d%s", bsc->udp_nr_links, VTY_NEWLINE);
+ vty_out(vty, " isup pass-through %d%s", app->isup_pass, VTY_NEWLINE);
+
+ if (msc) {
+ vty_out(vty, " msc ip %s%s", msc->ip, VTY_NEWLINE);
+ vty_out(vty, " msc ip-dscp %d%s", msc->dscp, VTY_NEWLINE);
+ vty_out(vty, " msc token %s%s", msc->token, VTY_NEWLINE);
+ }
+
+
+ return CMD_SUCCESS;
+}
+
+DEFUN(cfg_cell, cfg_cell_cmd,
+ "cellmgr", "Configure the Cellmgr")
+{
+ vty->node = CELLMGR_NODE;
+ return CMD_SUCCESS;
+}
+
+DEFUN(cfg_net_dpc, cfg_net_dpc_cmd,
+ "mtp dpc DPC_NR",
+ "Set the DPC to be used.")
+{
+ struct mtp_link_set *set = mtp_link_set_num(bsc, 0);
+ set->dpc = atoi(argv[0]);
+ return CMD_SUCCESS;
+}
+
+DEFUN(cfg_net_opc, cfg_net_opc_cmd,
+ "mtp opc OPC_NR",
+ "Set the OPC to be used.")
+{
+ struct mtp_link_set *set = mtp_link_set_num(bsc, 0);
+ set->opc = atoi(argv[0]);
+ return CMD_SUCCESS;
+}
+
+DEFUN(cfg_net_sccp_opc, cfg_net_sccp_opc_cmd,
+ "mtp sccp-opc OPC_NR",
+ "Set the SCCP OPC to be used.")
+{
+ struct mtp_link_set *set = mtp_link_set_num(bsc, 0);
+ set->sccp_opc = atoi(argv[0]);
+ return CMD_SUCCESS;
+}
+
+DEFUN(cfg_net_mtp_ni, cfg_net_mtp_ni_cmd,
+ "mtp ni NR",
+ "Set the MTP NI to be used.\n" "NR")
+{
+ struct mtp_link_set *set = mtp_link_set_num(bsc, 0);
+ set->ni = atoi(argv[0]);
+ return CMD_SUCCESS;
+}
+
+DEFUN(cfg_net_mtp_spare, cfg_net_mtp_spare_cmd,
+ "mtp spare NR",
+ "Set the MTP Spare to be used.\n" "NR")
+{
+ struct mtp_link_set *set = mtp_link_set_num(bsc, 0);
+ set->spare = atoi(argv[0]);
+ return CMD_SUCCESS;
+}
+
+
+DEFUN(cfg_udp_dst_ip, cfg_udp_dst_ip_cmd,
+ "udp dest ip IP",
+ "Set the IP when UDP mode is supposed to be used.")
+{
+ struct hostent *hosts;
+ struct in_addr *addr;
+
+ hosts = gethostbyname(argv[0]);
+ if (!hosts || hosts->h_length < 1 || hosts->h_addrtype != AF_INET) {
+ vty_out(vty, "Failed to resolve '%s'%s", argv[0], VTY_NEWLINE);
+ return CMD_WARNING;
+ }
+
+ addr = (struct in_addr *) hosts->h_addr_list[0];
+ bsc->udp_ip = talloc_strdup(NULL, inet_ntoa(*addr));
+ return CMD_SUCCESS;
+}
+
+DEFUN(cfg_udp_dst_port, cfg_udp_dst_port_cmd,
+ "udp dest port PORT_NR",
+ "If UDP mode is used specify the UDP dest port")
+{
+ bsc->udp_port = atoi(argv[0]);
+ return CMD_SUCCESS;
+}
+
+DEFUN(cfg_udp_src_port, cfg_udp_src_port_cmd,
+ "udp src port PORT_NR",
+ "Set the UDP source port to be used.")
+{
+ bsc->udp_src_port = atoi(argv[0]);
+ return CMD_SUCCESS;
+}
+
+DEFUN(cfg_udp_reset, cfg_udp_reset_cmd,
+ "udp reset TIMEOUT",
+ "Set the timeout to take the link down")
+{
+ bsc->udp_reset_timeout = atoi(argv[0]);
+ return CMD_SUCCESS;
+}
+
+DEFUN(cfg_udp_nr_links, cfg_udp_nr_links_cmd,
+ "udp number-links <1-32>",
+ "Set the number of links to use\n")
+{
+ bsc->udp_nr_links = atoi(argv[0]);
+ return CMD_SUCCESS;
+}
+
+DEFUN(cfg_sltm_once, cfg_sltm_once_cmd,
+ "mtp sltm once (0|1)",
+ "Send SLTMs until the link is established.")
+{
+ struct mtp_link_set *set = mtp_link_set_num(bsc, 0);
+ set->sltm_once = !!atoi(argv[0]);
+ return CMD_SUCCESS;
+}
+
+DEFUN(cfg_msc_ip, cfg_msc_ip_cmd,
+ "msc ip IP",
+ "Set the MSC IP")
+{
+ struct hostent *hosts;
+ struct in_addr *addr;
+ struct msc_connection *msc = msc_connection_num(bsc, 0);
+
+ if (!msc) {
+ vty_out(vty, "%%No MSC Connection defined in this app.%s", VTY_NEWLINE);
+ return CMD_WARNING;
+ }
+
+ hosts = gethostbyname(argv[0]);
+ if (!hosts || hosts->h_length < 1 || hosts->h_addrtype != AF_INET) {
+ vty_out(vty, "Failed to resolve '%s'%s", argv[0], VTY_NEWLINE);
+ return CMD_WARNING;
+ }
+
+ addr = (struct in_addr *) hosts->h_addr_list[0];
+
+ if (msc->ip)
+ talloc_free(msc->ip);
+ msc->ip = talloc_strdup(msc, inet_ntoa(*addr));
+ return CMD_SUCCESS;
+}
+
+DEFUN(cfg_msc_ip_dscp, cfg_msc_ip_dscp_cmd,
+ "msc ip-dscp <0-255>",
+ "Set the IP DSCP on the A-link\n"
+ "Set the DSCP in IP packets to the MSC")
+{
+ struct msc_connection *msc = msc_connection_num(bsc, 0);
+
+ if (!msc) {
+ vty_out(vty, "%%No MSC Connection defined in this app.%s", VTY_NEWLINE);
+ return CMD_WARNING;
+ }
+
+ msc->dscp = atoi(argv[0]);
+ return CMD_SUCCESS;
+}
+
+ALIAS_DEPRECATED(cfg_msc_ip_dscp, cfg_msc_ip_tos_cmd,
+ "msc ip-tos <0-255>",
+ "Set the IP DSCP on the A-link\n"
+ "Set the DSCP in IP packets to the MSC")
+
+DEFUN(cfg_msc_token, cfg_msc_token_cmd,
+ "msc token TOKEN",
+ "Set the Token to be used for the MSC")
+{
+ struct msc_connection *msc = msc_connection_num(bsc, 0);
+
+ if (!msc) {
+ vty_out(vty, "%%No MSC Connection defined in this app.%s", VTY_NEWLINE);
+ return CMD_WARNING;
+ }
+
+ if (msc->token)
+ talloc_free(msc->token);
+ msc->token = talloc_strdup(msc, argv[0]);
+ return CMD_SUCCESS;
+}
+
+DEFUN(cfg_ping_time, cfg_ping_time_cmd,
+ "timeout ping NR",
+ "Set the PING interval. Negative to disable it")
+{
+ struct msc_connection *msc = msc_connection_num(bsc, 0);
+
+ if (!msc) {
+ vty_out(vty, "%%No MSC Connection defined in this app.%s", VTY_NEWLINE);
+ return CMD_WARNING;
+ }
+
+ msc->ping_time = atoi(argv[0]);
+ return CMD_SUCCESS;
+}
+
+DEFUN(cfg_pong_time, cfg_pong_time_cmd,
+ "timeout pong NR",
+ "Set the PING interval. Negative to disable it")
+{
+ struct msc_connection *msc = msc_connection_num(bsc, 0);
+
+ if (!msc) {
+ vty_out(vty, "%%No MSC Connection defined in this app.%s", VTY_NEWLINE);
+ return CMD_WARNING;
+ }
+
+ msc->pong_time = atoi(argv[0]);
+ return CMD_SUCCESS;
+}
+
+DEFUN(cfg_msc_time, cfg_msc_time_cmd,
+ "timeout msc NR",
+ "Set the MSC connect timeout")
+{
+ struct msc_connection *msc = msc_connection_num(bsc, 0);
+
+ if (!msc) {
+ vty_out(vty, "%%No MSC Connection defined in this app.%s", VTY_NEWLINE);
+ return CMD_WARNING;
+ }
+
+ msc->msc_time = atoi(argv[0]);
+ return CMD_SUCCESS;
+}
+
+DEFUN(cfg_isup_pass, cfg_isup_pass_cmd,
+ "isup pass-through (0|1)",
+ "ISUP related functionality\n"
+ "Pass through all ISUP messages directly\n"
+ "Handle some messages locally\n" "Pass through everything\n")
+{
+ struct ss7_application *app = ss7_application_num(bsc, 0);
+ ss7_application_pass_isup(app, atoi(argv[0]));
+
+ return CMD_SUCCESS;
+}
+
+extern void cell_vty_init_cmds(void);
+void cell_vty_init(void)
+{
+ cmd_init(1);
+ vty_init(&vty_info);
+ logging_vty_add_cmds();
+
+ install_element(CONFIG_NODE, &cfg_cell_cmd);
+ install_node(&cell_node, config_write_cell);
+
+ install_element(CELLMGR_NODE, &cfg_net_dpc_cmd);
+ install_element(CELLMGR_NODE, &cfg_net_opc_cmd);
+ install_element(CELLMGR_NODE, &cfg_net_sccp_opc_cmd);
+ install_element(CELLMGR_NODE, &cfg_net_mtp_ni_cmd);
+ install_element(CELLMGR_NODE, &cfg_net_mtp_spare_cmd);
+ install_element(CELLMGR_NODE, &cfg_udp_dst_ip_cmd);
+ install_element(CELLMGR_NODE, &cfg_udp_dst_port_cmd);
+ install_element(CELLMGR_NODE, &cfg_udp_src_port_cmd);
+ install_element(CELLMGR_NODE, &cfg_udp_reset_cmd);
+ install_element(CELLMGR_NODE, &cfg_udp_nr_links_cmd);
+ install_element(CELLMGR_NODE, &cfg_sltm_once_cmd);
+ install_element(CELLMGR_NODE, &cfg_msc_ip_cmd);
+ install_element(CELLMGR_NODE, &cfg_msc_token_cmd);
+ install_element(CELLMGR_NODE, &cfg_msc_ip_dscp_cmd);
+ install_element(CELLMGR_NODE, &cfg_msc_ip_tos_cmd);
+ install_element(CELLMGR_NODE, &cfg_ping_time_cmd);
+ install_element(CELLMGR_NODE, &cfg_pong_time_cmd);
+ install_element(CELLMGR_NODE, &cfg_msc_time_cmd);
+ install_element(CELLMGR_NODE, &cfg_isup_pass_cmd);
+
+ cell_vty_init_cmds();
+}
+
+const char *openbsc_copyright = "";