diff options
author | Philipp Maier <pmaier@sysmocom.de> | 2017-06-30 14:15:44 +0200 |
---|---|---|
committer | Philipp Maier <pmaier@sysmocom.de> | 2017-06-30 14:15:44 +0200 |
commit | e80608d9fdacc6411d31def68dd00285642eecbd (patch) | |
tree | 17ee13bc23f5f29f606884de26e9e679b8c05bb2 /openbsc | |
parent | fc515efb41e4674c09f438a9664028f5b8da804d (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.
Diffstat (limited to 'openbsc')
-rw-r--r-- | openbsc/include/openbsc/bsc_msc_data.h | 10 | ||||
-rw-r--r-- | openbsc/src/osmo-bsc/osmo_bsc_bssap.c | 2 | ||||
-rw-r--r-- | openbsc/src/osmo-bsc/osmo_bsc_main.c | 18 | ||||
-rw-r--r-- | openbsc/src/osmo-bsc/osmo_bsc_sigtran.c | 57 | ||||
-rw-r--r-- | openbsc/src/osmo-bsc/osmo_bsc_vty.c | 89 |
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); |