aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorPhilipp Maier <pmaier@sysmocom.de>2017-06-30 14:15:44 +0200
committerPhilipp Maier <pmaier@sysmocom.de>2017-06-30 14:15:44 +0200
commite80608d9fdacc6411d31def68dd00285642eecbd (patch)
tree17ee13bc23f5f29f606884de26e9e679b8c05bb2
parentfc515efb41e4674c09f438a9664028f5b8da804d (diff)
osmo-bsc: Make SCCP-Addresses configurable via VTY
Add VTY commands to configure the sccp-address of the BSC and the one of the MSC.
-rw-r--r--openbsc/include/openbsc/bsc_msc_data.h10
-rw-r--r--openbsc/src/osmo-bsc/osmo_bsc_bssap.c2
-rw-r--r--openbsc/src/osmo-bsc/osmo_bsc_main.c18
-rw-r--r--openbsc/src/osmo-bsc/osmo_bsc_sigtran.c57
-rw-r--r--openbsc/src/osmo-bsc/osmo_bsc_vty.c89
5 files changed, 135 insertions, 41 deletions
diff --git a/openbsc/include/openbsc/bsc_msc_data.h b/openbsc/include/openbsc/bsc_msc_data.h
index 0d7ec224d..e97ab13fc 100644
--- a/openbsc/include/openbsc/bsc_msc_data.h
+++ b/openbsc/include/openbsc/bsc_msc_data.h
@@ -111,6 +111,16 @@ struct bsc_msc_data {
char *ussd_grace_txt;
char *acc_lst_name;
+
+ /* Sigtran connection data */
+ struct {
+ struct osmo_ss7_instance *ss7;
+ struct osmo_sccp_instance *sccp;
+ struct osmo_sccp_user *sccp_user;
+ struct osmo_sccp_addr g_calling_addr;
+ struct osmo_sccp_addr g_called_addr;
+ struct a_reset_ctx *reset;
+ } a;
};
/*
diff --git a/openbsc/src/osmo-bsc/osmo_bsc_bssap.c b/openbsc/src/osmo-bsc/osmo_bsc_bssap.c
index ee7557c85..6c3169d87 100644
--- a/openbsc/src/osmo-bsc/osmo_bsc_bssap.c
+++ b/openbsc/src/osmo-bsc/osmo_bsc_bssap.c
@@ -198,7 +198,7 @@ static int bssmap_handle_reset_ack(struct bsc_msc_data *msc,
/* Inform the FSM that controls the RESET/RESET-ACK procedure
* that we have successfully received the reset-ack message */
- a_reset_ack_confirm(msc->msc_con->reset);
+ a_reset_ack_confirm(msc->a.reset);
return 0;
}
diff --git a/openbsc/src/osmo-bsc/osmo_bsc_main.c b/openbsc/src/osmo-bsc/osmo_bsc_main.c
index 490a5ea6c..68f8b492d 100644
--- a/openbsc/src/osmo-bsc/osmo_bsc_main.c
+++ b/openbsc/src/osmo-bsc/osmo_bsc_main.c
@@ -217,6 +217,10 @@ int main(int argc, char **argv)
bsc_msg_lst_vty_init(tall_bsc_ctx, &access_lists, BSC_NODE);
ctrl_vty_init(tall_bsc_ctx);
+ /* Initalize SS7 */
+ osmo_ss7_init();
+ osmo_ss7_vty_init_sg();
+
INIT_LLIST_HEAD(&access_lists);
/* parse options */
@@ -269,20 +273,6 @@ int main(int argc, char **argv)
}
}
-
- llist_for_each_entry(msc, &bsc_gsmnet->bsc_data->mscs, entry) {
- /* FIXME: This has to come from a config file */
- osmo_sccp_make_addr_pc_ssn(&msc->msc_con->g_calling_addr,
- 42, SCCP_SSN_BSSAP);
- osmo_sccp_make_addr_pc_ssn(&msc->msc_con->g_called_addr,
- 1, SCCP_SSN_BSSAP);
- }
-
-// if (osmo_bsc_sccp_init(bsc_gsmnet) != 0) {
-// LOGP(DNM, LOGL_ERROR, "Failed to register SCCP.\n");
-// exit(1);
-// }
-
if (osmo_bsc_sigtran_init(&bsc_gsmnet->bsc_data->mscs) != 0) {
LOGP(DNM, LOGL_ERROR, "Failed to initalize sigtran backhaul.\n");
exit(1);
diff --git a/openbsc/src/osmo-bsc/osmo_bsc_sigtran.c b/openbsc/src/osmo-bsc/osmo_bsc_sigtran.c
index 3b1a1c0f9..451329271 100644
--- a/openbsc/src/osmo-bsc/osmo_bsc_sigtran.c
+++ b/openbsc/src/osmo-bsc/osmo_bsc_sigtran.c
@@ -41,8 +41,15 @@ static struct llist_head *msc_list;
#define RESET_INTERVAL 1 /* sek */
#define SCCP_MSG_MAXSIZE 1024
+/* Internal list with connections we currently maintain. This
+ * list is of type struct osmo_bsc_sccp_con */
static LLIST_HEAD(active_connections);
+/* The SCCP stack will not assign connection IDs to us automatically, we
+ * will do this ourselves using a counter variable, that counts one up
+ * for every new connection */
+static uint32_t conn_id_counter;
+
/* Helper function to Check if the given connection id is already assigned */
static struct osmo_bsc_sccp_con *get_bsc_conn_by_conn_id(int conn_id)
{
@@ -60,14 +67,14 @@ static struct osmo_bsc_sccp_con *get_bsc_conn_by_conn_id(int conn_id)
/* Pick a free connection id */
static int pick_free_conn_id(struct bsc_msc_data *msc)
{
- int conn_id = msc->msc_con->conn_id_counter;
+ int conn_id = conn_id_counter;
int i;
for (i = 0; i < 0xFFFFFF; i++) {
conn_id++;
conn_id &= 0xFFFFFF;
if (get_bsc_conn_by_conn_id(conn_id) == false) {
- msc->msc_con->conn_id_counter = conn_id;
+ conn_id_counter = conn_id;
return conn_id;
}
}
@@ -81,8 +88,8 @@ static void osmo_bsc_sigtran_tx_reset(struct bsc_msc_data *msc)
struct msgb *msg;
LOGP(DMSC, LOGL_NOTICE, "Sending RESET to MSC No.: %i\n", msc->nr);
msg = gsm0808_create_reset();
- osmo_sccp_tx_unitdata_msg(msc->msc_con->sccp_user, &msc->msc_con->g_calling_addr,
- &msc->msc_con->g_called_addr, msg);
+ osmo_sccp_tx_unitdata_msg(msc->a.sccp_user, &msc->a.g_calling_addr,
+ &msc->a.g_called_addr, msg);
}
/* Send reset-ack to MSC */
@@ -91,17 +98,16 @@ void osmo_bsc_sigtran_tx_reset_ack(struct bsc_msc_data *msc)
struct msgb *msg;
LOGP(DMSC, LOGL_NOTICE, "Sending RESET RACK to MSC No.: %i\n", msc->nr);
msg = gsm0808_create_reset_ack();
- osmo_sccp_tx_unitdata_msg(msc->msc_con->sccp_user, &msc->msc_con->g_calling_addr,
- &msc->msc_con->g_called_addr, msg);
+ osmo_sccp_tx_unitdata_msg(msc->a.sccp_user, &msc->a.g_calling_addr,
+ &msc->a.g_called_addr, msg);
}
-
/* Find an MSC by its sigtran point code */
static struct bsc_msc_data *get_msc_by_addr(struct osmo_sccp_addr *calling_addr)
{
struct bsc_msc_data *msc;
llist_for_each_entry(msc, msc_list, entry) {
- if (memcmp(calling_addr, &msc->msc_con->g_called_addr, sizeof(*calling_addr)) == 0)
+ if (memcmp(calling_addr, &msc->a.g_called_addr, sizeof(*calling_addr)) == 0)
return msc;
}
@@ -180,7 +186,7 @@ static int sccp_sap_up(struct osmo_prim_hdr *oph, void *_scu)
/* Incoming data is a sign of a vital connection */
bsc_con = get_bsc_conn_by_conn_id(scu_prim->u.disconnect.conn_id);
if (bsc_con)
- a_reset_conn_success(bsc_con->msc->msc_con->reset);
+ a_reset_conn_success(bsc_con->msc->a.reset);
rc = handle_data_from_msc(scu_prim->u.data.conn_id, oph->msg);
break;
@@ -200,7 +206,7 @@ static int sccp_sap_up(struct osmo_prim_hdr *oph, void *_scu)
/* We might have a connectivity problem. Maybe we need to go
* through the reset procedure again? */
if (scu_prim->u.disconnect.cause == 0)
- a_reset_conn_fail(bsc_con->msc->msc_con->reset);
+ a_reset_conn_fail(bsc_con->msc->a.reset);
rc = osmo_bsc_sigtran_del_conn(bsc_con);
}
@@ -227,7 +233,7 @@ enum bsc_con osmo_bsc_sigtran_new_conn(struct gsm_subscriber_connection *conn, s
LOGP(DMSC, LOGL_NOTICE, "Initalizing resources for new SIGTRAN connection to MSC No.: %i...\n", msc->nr);
- if (a_reset_conn_ready(msc->msc_con->reset) == false) {
+ if (a_reset_conn_ready(msc->a.reset) == false) {
LOGP(DMSC, LOGL_ERROR, "MSC is not connected. Dropping.\n");
return BSC_CON_REJECT_NO_LINK;
}
@@ -272,7 +278,7 @@ int osmo_bsc_sigtran_open_conn(struct osmo_bsc_sccp_con *conn, struct msgb *msg)
msc = conn->msc;
- if (a_reset_conn_ready(msc->msc_con->reset) == false) {
+ if (a_reset_conn_ready(msc->a.reset) == false) {
LOGP(DMSC, LOGL_ERROR, "MSC is not connected. Dropping.\n");
return -EINVAL;
}
@@ -280,8 +286,8 @@ int osmo_bsc_sigtran_open_conn(struct osmo_bsc_sccp_con *conn, struct msgb *msg)
conn_id = conn->conn_id;
LOGP(DMSC, LOGL_NOTICE, "Opening new SIGTRAN connection (id=%i) to MSC No.: %i...\n", conn_id, msc->nr);
- rc = osmo_sccp_tx_conn_req_msg(msc->msc_con->sccp_user, conn_id, &msc->msc_con->g_calling_addr,
- &msc->msc_con->g_called_addr, msg);
+ rc = osmo_sccp_tx_conn_req_msg(msc->a.sccp_user, conn_id, &msc->a.g_calling_addr,
+ &msc->a.g_called_addr, msg);
return rc;
}
@@ -299,7 +305,7 @@ int osmo_bsc_sigtran_send(struct osmo_bsc_sccp_con *conn, struct msgb *msg)
msc = conn->msc;
- if (a_reset_conn_ready(msc->msc_con->reset) == false) {
+ if (a_reset_conn_ready(msc->a.reset) == false) {
LOGP(DMSC, LOGL_ERROR, "MSC is not connected. Dropping.\n");
return -EINVAL;
}
@@ -308,7 +314,7 @@ int osmo_bsc_sigtran_send(struct osmo_bsc_sccp_con *conn, struct msgb *msg)
LOGP(DMSC, LOGL_DEBUG, "Sending connection (id=%i) oriented data to MSC No.: %i...\n", conn_id, msc->nr);
- rc = osmo_sccp_tx_data_msg(msc->msc_con->sccp_user, conn_id, msg);
+ rc = osmo_sccp_tx_data_msg(msc->a.sccp_user, conn_id, msg);
return rc;
}
@@ -330,7 +336,7 @@ int osmo_bsc_sigtran_del_conn(struct osmo_bsc_sccp_con *conn)
/* This bahaviour might be caused by a bad connection. Maybe we
* will have to go through the reset procedure again */
- a_reset_conn_fail(conn->msc->msc_con->reset);
+ a_reset_conn_fail(conn->msc->a.reset);
}
llist_del(&conn->entry);
@@ -372,7 +378,6 @@ void osmo_bsc_sigtran_reset(struct bsc_msc_data *msc)
bsc_notify_msc_lost(conn);
osmo_bsc_sigtran_del_conn(conn);
}
- msc->msc_con->conn_id_counter = 0;
}
/* Callback function: Close all open connections */
@@ -380,7 +385,7 @@ static void osmo_bsc_sigtran_reset_cb(void *priv)
{
struct bsc_msc_data *msc = (struct bsc_msc_data*) priv;
- /* Shut down all ongoint traffic */
+ /* Shut down all ongoing traffic */
osmo_bsc_sigtran_reset(msc);
/* Send reset to MSC */
@@ -396,23 +401,23 @@ int osmo_bsc_sigtran_init(struct llist_head *mscs)
OSMO_ASSERT(mscs);
- osmo_ss7_init();
-
msc_list = mscs;
+ conn_id_counter = 0;
+
llist_for_each_entry(msc, msc_list, entry) {
snprintf(msc_name, sizeof(msc_name), "MSC No.: %u", msc->nr);
LOGP(DMSC, LOGL_NOTICE, "Initalizing SCCP connection to %s\n", msc_name);
/* SCCP Protocol stack */
- msc->msc_con->sccp =
- osmo_sccp_simple_client(NULL, msc_name, msc->msc_con->g_calling_addr.pc,
+ msc->a.sccp =
+ osmo_sccp_simple_client(NULL, msc_name, msc->a.g_calling_addr.pc,
OSMO_SS7_ASP_PROT_M3UA, 0, NULL, M3UA_PORT, "127.0.0.1");
- msc->msc_con->sccp_user =
- osmo_sccp_user_bind(msc->msc_con->sccp, msc_name, sccp_sap_up, SCCP_SSN_BSSAP);
+ msc->a.sccp_user =
+ osmo_sccp_user_bind(msc->a.sccp, msc_name, sccp_sap_up, SCCP_SSN_BSSAP);
/* Start MSC reset procedure */
- msc->msc_con->reset = a_reset_alloc(NULL, msc_name, osmo_bsc_sigtran_reset_cb, msc);
+ msc->a.reset = a_reset_alloc(msc, msc_name, osmo_bsc_sigtran_reset_cb, msc);
}
return 0;
diff --git a/openbsc/src/osmo-bsc/osmo_bsc_vty.c b/openbsc/src/osmo-bsc/osmo_bsc_vty.c
index 2e2e99bfd..5d6491047 100644
--- a/openbsc/src/osmo-bsc/osmo_bsc_vty.c
+++ b/openbsc/src/osmo-bsc/osmo_bsc_vty.c
@@ -184,6 +184,18 @@ static void write_msc(struct vty *vty, struct bsc_msc_data *msc)
/* write amr options */
write_msc_amr_options(vty, msc);
+
+ /* write sccp connection configuration */
+ if (msc->a.ss7) {
+ vty_out(vty, " cs7-instance %u%s", msc->a.ss7->cfg.id,
+ VTY_NEWLINE);
+ vty_out(vty, " calling-addr %s%s",
+ osmo_sccp_name_by_addr(&msc->a.g_calling_addr,
+ msc->a.ss7), VTY_NEWLINE);
+ vty_out(vty, " called-addr %s%s",
+ osmo_sccp_name_by_addr(&msc->a.g_called_addr,
+ msc->a.ss7), VTY_NEWLINE);
+ }
}
static int config_write_msc(struct vty *vty)
@@ -685,6 +697,80 @@ DEFUN(cfg_msc_no_acc_lst_name,
return CMD_SUCCESS;
}
+DEFUN(cfg_msc_cs7_instance,
+ cfg_msc_cs7_instance_cmd,
+ "cs7-instance <0-15>",
+ "Set Associated SS7 instance.\n" "SS7 instance reference number\n")
+{
+ struct bsc_msc_data *msc = bsc_msc_data(vty);
+ uint32_t inst_id = atoi(argv[0]);
+ struct osmo_ss7_instance *inst;
+
+ inst = osmo_ss7_instance_find(inst_id);
+ if (!inst) {
+ vty_out(vty, "No SS7 instance %d found%s", inst_id,
+ VTY_NEWLINE);
+ return CMD_WARNING;
+ }
+
+ msc->a.ss7 = inst;
+ return CMD_SUCCESS;
+}
+
+DEFUN(cfg_msc_cs7_calling_addr,
+ cfg_msc_cs7_calling_addr_cmd,
+ "calling-addr NAME",
+ "Calling Address (local address of this BSC)\n" "SCCP address name\n")
+{
+ struct bsc_msc_data *msc = bsc_msc_data(vty);
+ const char *calling_addr_name = argv[0];
+ struct osmo_sccp_addr *calling_addr;
+
+ if (!msc->a.ss7) {
+ vty_out(vty, "cs7-instance instance must be configured first%s",
+ VTY_NEWLINE);
+ return CMD_WARNING;
+ }
+
+ calling_addr = osmo_sccp_addr_by_name(calling_addr_name, msc->a.ss7);
+ if (!calling_addr) {
+ vty_out(vty, "No sccp address %s found%s", calling_addr_name,
+ VTY_NEWLINE);
+ return CMD_WARNING;
+ }
+
+ memcpy(&msc->a.g_calling_addr, calling_addr, sizeof(*calling_addr));
+
+ return CMD_SUCCESS;
+}
+
+DEFUN(cfg_msc_cs7_called_addr,
+ cfg_msc_cs7_called_addr_cmd,
+ "called-addr NAME",
+ "Called Address (remote address of the MSC)\n" "SCCP address name\n")
+{
+ struct bsc_msc_data *msc = bsc_msc_data(vty);
+ const char *called_addr_name = argv[0];
+ struct osmo_sccp_addr *called_addr;
+
+ if (!msc->a.ss7) {
+ vty_out(vty, "cs7-instance instance must be configured first%s",
+ VTY_NEWLINE);
+ return CMD_WARNING;
+ }
+
+ called_addr = osmo_sccp_addr_by_name(called_addr_name, msc->a.ss7);
+ if (!called_addr) {
+ vty_out(vty, "No sccp address %s found%s", called_addr_name,
+ VTY_NEWLINE);
+ return CMD_WARNING;
+ }
+
+ memcpy(&msc->a.g_called_addr, called_addr, sizeof(*called_addr));
+
+ return CMD_SUCCESS;
+}
+
DEFUN(cfg_net_bsc_mid_call_text,
cfg_net_bsc_mid_call_text_cmd,
"mid-call-text .TEXT",
@@ -931,6 +1017,9 @@ int bsc_vty_init_extra(void)
install_element(MSC_NODE, &cfg_net_msc_amr_4_75_cmd);
install_element(MSC_NODE, &cfg_msc_acc_lst_name_cmd);
install_element(MSC_NODE, &cfg_msc_no_acc_lst_name_cmd);
+ install_element(MSC_NODE, &cfg_msc_cs7_instance_cmd);
+ install_element(MSC_NODE, &cfg_msc_cs7_calling_addr_cmd);
+ install_element(MSC_NODE, &cfg_msc_cs7_called_addr_cmd);
install_element_ve(&show_statistics_cmd);
install_element_ve(&show_mscs_cmd);