aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--openbsc/include/openbsc/a_iface.h16
-rw-r--r--openbsc/include/openbsc/a_reset.h5
-rw-r--r--openbsc/include/openbsc/bsc_msc.h7
-rw-r--r--openbsc/include/openbsc/bsc_msc_data.h10
-rw-r--r--openbsc/include/openbsc/gsm_data.h5
-rw-r--r--openbsc/src/libcommon-cs/a_reset.c37
-rw-r--r--openbsc/src/libcommon-cs/common_cs.c2
-rw-r--r--openbsc/src/libmsc/a_iface.c131
-rw-r--r--openbsc/src/libmsc/msc_vty.c104
-rw-r--r--openbsc/src/osmo-bsc/osmo_bsc_bssap.c2
-rw-r--r--openbsc/src/osmo-bsc/osmo_bsc_main.c22
-rw-r--r--openbsc/src/osmo-bsc/osmo_bsc_sigtran.c45
-rw-r--r--openbsc/src/osmo-bsc/osmo_bsc_vty.c89
-rw-r--r--openbsc/src/osmo-msc/msc_main.c2
14 files changed, 367 insertions, 110 deletions
diff --git a/openbsc/include/openbsc/a_iface.h b/openbsc/include/openbsc/a_iface.h
index 6da2715e9..22651625f 100644
--- a/openbsc/include/openbsc/a_iface.h
+++ b/openbsc/include/openbsc/a_iface.h
@@ -31,13 +31,19 @@ struct bsc_context {
struct osmo_sccp_addr calling_addr; /* MSC (local) */
/* Automatically filled up by a_init() */
- struct a_reset_ctx reset; /* Reset FSM (one per BSC) */
- struct osmo_sccp_user *sccp_user; /* SCCP user (the same for all) */
+ char name[512];
+ struct a_reset_ctx *reset; /* Reset FSM */
+ struct osmo_ss7_instance *ss7;
+ struct osmo_sccp_instance *sccp;
+ struct osmo_sccp_user *sccp_user;
};
-/* Initalize A interface connection between to MSC and BSC */
-int a_init(void *ctx, const char *name, uint32_t local_pc, const char *listen_addr,
- const char *remote_addr, uint16_t local_port, struct gsm_network *network);
+/* Initalize a new A connection for a remote bsc (called by VTY) */
+int a_init(struct gsm_network *network, struct osmo_sccp_addr *calling_addr, struct osmo_sccp_addr *called_addr,
+ struct osmo_ss7_instance *ss7);
+
+/* Drop a no longer used A connection (called by VTY) */
+void a_drop(struct osmo_sccp_addr *calling_addr, struct osmo_sccp_addr *called_addr);
/* Send DTAP message via A-interface */
int a_iface_tx_dtap(struct msgb *msg);
diff --git a/openbsc/include/openbsc/a_reset.h b/openbsc/include/openbsc/a_reset.h
index 124cf13f1..343454a28 100644
--- a/openbsc/include/openbsc/a_reset.h
+++ b/openbsc/include/openbsc/a_reset.h
@@ -45,7 +45,10 @@ struct a_reset_ctx {
};
/* Create and start state machine which handles the reset/reset-ack procedure */
-void a_reset_start(struct a_reset_ctx *reset);
+struct a_reset_ctx *a_reset_alloc(void *ctx, char *name, void *cb, void *priv);
+
+/* Tear down state machine */
+void a_reset_free(struct a_reset_ctx *reset);
/* Confirm that we sucessfully received a reset acknowlege message */
void a_reset_ack_confirm(struct a_reset_ctx *reset);
diff --git a/openbsc/include/openbsc/bsc_msc.h b/openbsc/include/openbsc/bsc_msc.h
index 35b8654d5..e52d92e77 100644
--- a/openbsc/include/openbsc/bsc_msc.h
+++ b/openbsc/include/openbsc/bsc_msc.h
@@ -55,13 +55,6 @@ struct bsc_msc_connection {
struct osmo_timer_list timeout_timer;
struct msgb *pending_msg;
-
- /* Sigtran connection data */
- 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;
};
struct bsc_msc_connection *bsc_msc_create(void *ctx, struct llist_head *dest);
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/include/openbsc/gsm_data.h b/openbsc/include/openbsc/gsm_data.h
index 84855aca3..9053f07e7 100644
--- a/openbsc/include/openbsc/gsm_data.h
+++ b/openbsc/include/openbsc/gsm_data.h
@@ -479,8 +479,9 @@ struct gsm_network {
enum nsap_addr_enc rab_assign_addr_enc;
} iu;
- /* A list with all associated BSCs */
- struct llist_head bscs;
+ struct {
+ struct llist_head bscs;
+ } a;
};
struct osmo_esme;
diff --git a/openbsc/src/libcommon-cs/a_reset.c b/openbsc/src/libcommon-cs/a_reset.c
index 7eebb152d..a6110a22b 100644
--- a/openbsc/src/libcommon-cs/a_reset.c
+++ b/openbsc/src/libcommon-cs/a_reset.c
@@ -132,18 +132,47 @@ static struct osmo_fsm fsm = {
};
/* Create and start state machine which handles the reset/reset-ack procedure */
-void a_reset_start(struct a_reset_ctx *reset)
+struct a_reset_ctx *a_reset_alloc(void *ctx, char *name, void *cb, void *priv)
{
- OSMO_ASSERT(reset);
+ OSMO_ASSERT(name);
+
+ struct a_reset_ctx *reset;
- osmo_fsm_register(&fsm);
+ /* Register the fsm description (if not already done) */
+ if (osmo_fsm_find_by_name(fsm.name) != &fsm)
+ osmo_fsm_register(&fsm);
+
+ /* Allocate and configure a new fsm instance */
+ reset = talloc_zero(ctx, struct a_reset_ctx);
+ OSMO_ASSERT(reset);
+ reset->priv = priv;
+ reset->cb = cb;
+ strncpy(reset->name, name, sizeof(reset->name));
+ reset->conn_loss_counter = 0;
reset->fsm = osmo_fsm_inst_alloc(&fsm, NULL, NULL, LOGL_DEBUG, "FSM RESET INST");
OSMO_ASSERT(reset->fsm);
-
reset->fsm->priv = reset;
+ LOGP(DMSC, LOGL_NOTICE, "(%s) reset handler fsm created.\n", reset->name);
/* kick off reset-ack sending mechanism */
osmo_fsm_inst_state_chg(reset->fsm, ST_DISC, RESET_RESEND_INTERVAL, RESET_RESEND_TIMER_NO);
+
+ return reset;
+}
+
+/* Tear down state machine */
+void a_reset_free(struct a_reset_ctx *reset)
+{
+ OSMO_ASSERT(reset);
+ OSMO_ASSERT(reset->fsm);
+
+ osmo_fsm_inst_free(reset->fsm);
+ reset->fsm = NULL;
+
+ memset(reset, 0, sizeof(*reset));
+ talloc_free(reset);
+
+ LOGP(DMSC, LOGL_NOTICE, "(%s) reset handler fsm destroyed.\n", reset->name);
}
/* Confirm that we sucessfully received a reset acknowlege message */
diff --git a/openbsc/src/libcommon-cs/common_cs.c b/openbsc/src/libcommon-cs/common_cs.c
index 59d496d28..6e9bb4c33 100644
--- a/openbsc/src/libcommon-cs/common_cs.c
+++ b/openbsc/src/libcommon-cs/common_cs.c
@@ -65,7 +65,7 @@ struct gsm_network *gsm_network_init(void *ctx,
INIT_LLIST_HEAD(&net->trans_list);
INIT_LLIST_HEAD(&net->upqueue);
INIT_LLIST_HEAD(&net->subscr_conns);
- INIT_LLIST_HEAD(&net->bscs);
+ INIT_LLIST_HEAD(&net->a.bscs);
net->bsc_subscribers = talloc_zero(net, struct llist_head);
INIT_LLIST_HEAD(net->bsc_subscribers);
diff --git a/openbsc/src/libmsc/a_iface.c b/openbsc/src/libmsc/a_iface.c
index fbd5b9329..1ebb645fa 100644
--- a/openbsc/src/libmsc/a_iface.c
+++ b/openbsc/src/libmsc/a_iface.c
@@ -115,9 +115,9 @@ static struct a_reset_ctx *get_reset_ctx_by_sccp_addr(struct osmo_sccp_addr *add
if (!addr)
return NULL;
- llist_for_each_entry(bsc_ctx, &gsm_network->bscs, list) {
+ llist_for_each_entry(bsc_ctx, &gsm_network->a.bscs, list) {
if (memcmp(&bsc_ctx->called_addr, addr, sizeof(*addr)) == 0)
- return &bsc_ctx->reset;
+ return bsc_ctx->reset;
}
LOGP(DMSC, LOGL_ERROR, "The calling BSC (%s) is unknown to this MSC ...\n",
@@ -199,8 +199,8 @@ int a_iface_tx_paging(const char *imsi, uint32_t tmsi, uint16_t lac)
cil.id_list_len = 1;
/* Deliver paging request to all known BSCs */
- llist_for_each_entry(bsc_ctx, &gsm_network->bscs, list) {
- if (a_reset_conn_ready(&bsc_ctx->reset)) {
+ llist_for_each_entry(bsc_ctx, &gsm_network->a.bscs, list) {
+ if (a_reset_conn_ready(bsc_ctx->reset)) {
LOGP(DMSC, LOGL_DEBUG,
"Passing paging message from MSC %s to BSC %s (imsi=%s, tmsi=0x%08x, lac=%u)\n",
osmo_sccp_addr_dump(&bsc_ctx->calling_addr),
@@ -444,7 +444,6 @@ static int sccp_sap_up(struct osmo_prim_hdr *oph, void *_scu)
a_conn_info.called_addr = &scu_prim->u.unitdata.called_addr;
a_conn_info.calling_addr = &scu_prim->u.unitdata.calling_addr;
a_conn_info.reset = get_reset_ctx_by_sccp_addr(&scu_prim->u.unitdata.calling_addr);
-
DEBUGP(DMSC, "N-UNITDATA.ind(%s)\n", osmo_hexdump(msgb_l2(oph->msg), msgb_l2len(oph->msg)));
sccp_rx_udt(scu, &a_conn_info, oph->msg);
break;
@@ -487,61 +486,105 @@ static void a_reset_cb(void *priv)
struct msgb *msg;
struct bsc_context *bsc_ctx = (struct bsc_context*) priv;
+ /* Skip if the A interface is not properly initalized yet */
+ if (!gsm_network)
+ return;
+
/* Clear all now orphaned subscriber connections */
a_clear_all(bsc_ctx->sccp_user, &bsc_ctx->called_addr);
+ /* Send reset to the remote BSC */
LOGP(DMSC, LOGL_NOTICE, "Sending RESET to BSC %s\n", osmo_sccp_addr_dump(&bsc_ctx->called_addr));
msg = gsm0808_create_reset();
osmo_sccp_tx_unitdata_msg(bsc_ctx->sccp_user, &bsc_ctx->calling_addr,
&bsc_ctx->called_addr, msg);
}
-/* Initalize A interface connection between to MSC and BSC */
-int a_init(void *ctx, const char *name, uint32_t local_pc,
- const char *listen_addr, const char *remote_addr, uint16_t local_port, struct gsm_network *network)
+/* Initalize a new A connection for a remote bsc (called by VTY) */
+int a_init(struct gsm_network *network, struct osmo_sccp_addr *calling_addr, struct osmo_sccp_addr *called_addr,
+ struct osmo_ss7_instance *ss7)
{
+ struct bsc_context *bsc_ctx;
+ OSMO_ASSERT(network);
+ OSMO_ASSERT(calling_addr);
+ OSMO_ASSERT(called_addr);
+ OSMO_ASSERT(ss7);
-#define SSN_BSSAP 254 /* SCCP_SSN_BSSAP */
-#define SENDER_PC 1 /* Our local point code */
-
- /* FIXME: Remove hardcoded parameters, use parameters in parameter list */
- struct osmo_sccp_instance *sccp;
- struct osmo_sccp_user *scu;
- struct bsc_context *bsc_ctx;
+ /* Set GSM network variable */
+ /* NOTE: There can only be one gsm network! */
+ if (gsm_network != NULL) {
+ OSMO_ASSERT(gsm_network == network);
+ } else
+ gsm_network = network;
- LOGP(DMSC, LOGL_NOTICE, "Initalizing SCCP connection to stp...\n");
+ /* Generate and fill up a new bsc context */
+ bsc_ctx = talloc_zero(gsm_network, struct bsc_context);
+ OSMO_ASSERT(bsc_ctx);
- gsm_network = network;
- osmo_ss7_init();
+ snprintf(bsc_ctx->name, sizeof(bsc_ctx->name), "%s/%s", osmo_sccp_name_by_addr(calling_addr, ss7),
+ osmo_sccp_name_by_addr(called_addr, ss7));
- /* SCCP Protocol stack */
- sccp =
- osmo_sccp_simple_client(NULL, "osmo-msc", SENDER_PC, OSMO_SS7_ASP_PROT_M3UA, 0, NULL, M3UA_PORT,
+ bsc_ctx->ss7 = ss7;
+ bsc_ctx->sccp =
+ osmo_sccp_simple_client(NULL, bsc_ctx->name, calling_addr->pc, OSMO_SS7_ASP_PROT_M3UA, 0, NULL, M3UA_PORT,
"127.0.0.1");
- scu = osmo_sccp_user_bind(sccp, "osmo-msc", sccp_sap_up, SSN_BSSAP);
-
- /* Add some BSCs to the context list */
- /* FIXME: Make this configurable (VTY!) */
- bsc_ctx = talloc_zero(NULL, struct bsc_context);
- bsc_ctx->reset.priv = bsc_ctx;
- bsc_ctx->reset.cb = a_reset_cb;
- llist_add_tail(&bsc_ctx->list, &gsm_network->bscs);
- bsc_ctx->called_addr.presence = OSMO_SCCP_ADDR_T_SSN | OSMO_SCCP_ADDR_T_PC;
- bsc_ctx->called_addr.ssn = SCCP_SSN_BSSAP;
- bsc_ctx->called_addr.ri = OSMO_SCCP_RI_SSN_PC;
- bsc_ctx->called_addr.pc = 23;
- bsc_ctx->calling_addr.presence = OSMO_SCCP_ADDR_T_SSN | OSMO_SCCP_ADDR_T_PC;
- bsc_ctx->calling_addr.ssn = SCCP_SSN_BSSAP;
- bsc_ctx->calling_addr.ri = OSMO_SCCP_RI_SSN_PC;
- bsc_ctx->calling_addr.pc = 1;
- bsc_ctx->sccp_user = scu;
- bsc_ctx = NULL;
-
- /* Start reset procedure for all BSC connections */
- llist_for_each_entry(bsc_ctx, &gsm_network->bscs, list) {
- a_reset_start(&bsc_ctx->reset);
- }
+ bsc_ctx->sccp_user = osmo_sccp_user_bind(bsc_ctx->sccp, bsc_ctx->name, sccp_sap_up, SCCP_SSN_BSSAP);
+
+ memcpy(&bsc_ctx->called_addr, called_addr, sizeof(*called_addr));
+ memcpy(&bsc_ctx->calling_addr, calling_addr, sizeof(*calling_addr));
+
+ llist_add_tail(&bsc_ctx->list, &gsm_network->a.bscs);
+
+ /* Start reset procedure to make the new connection active */
+ bsc_ctx->reset = a_reset_alloc(bsc_ctx, bsc_ctx->name, a_reset_cb, bsc_ctx);
+
+ LOGP(DMSC, LOGL_NOTICE, "Adding new MSC/BSC connection (%s), MSC=%s,", bsc_ctx->name,
+ osmo_sccp_addr_dump(calling_addr));
+ LOGPC(DMSC, LOGL_NOTICE, " BSC=%s...\n", osmo_sccp_addr_dump(called_addr));
return 0;
}
+
+/* Drop a no longer used A connection (called by VTY) */
+void a_drop(struct osmo_sccp_addr *calling_addr, struct osmo_sccp_addr *called_addr)
+{
+ struct bsc_context *bsc_ctx;
+ struct bsc_context *bsc_ctx_temp;
+
+ OSMO_ASSERT(calling_addr);
+ OSMO_ASSERT(called_addr);
+
+ /* Find the BSC context depending on the given addresses */
+ llist_for_each_entry_safe(bsc_ctx, bsc_ctx_temp, &gsm_network->a.bscs, list) {
+ if (memcmp(&bsc_ctx->calling_addr, calling_addr, sizeof(*calling_addr)) == 0
+ && memcmp(&bsc_ctx->called_addr, called_addr, sizeof(*called_addr)) == 0) {
+
+ OSMO_ASSERT(bsc_ctx->ss7);
+ OSMO_ASSERT(bsc_ctx->sccp);
+ OSMO_ASSERT(bsc_ctx->sccp_user);
+
+ LOGP(DMSC, LOGL_NOTICE, "Removing MSC/BSC connection (%s), MSC=%s,", bsc_ctx->name,
+ osmo_sccp_addr_dump(calling_addr));
+ LOGPC(DMSC, LOGL_NOTICE, " BSC=%s...\n", osmo_sccp_addr_dump(called_addr));
+
+ /* Perform the reset procedure one last time. This will also tear
+ * down all currently open connections. */
+ bsc_ctx->reset->cb(bsc_ctx->reset->priv);
+
+ /* Destroy reset handler FSM, reconnecting is no longer impossible */
+ a_reset_free(bsc_ctx->reset);
+
+ /* Destroy ss7 connection */
+ osmo_sccp_user_unbind(bsc_ctx->sccp_user);
+ osmo_sccp_instance_destroy(bsc_ctx->sccp);
+
+ /* Exterminate bsc context */
+ llist_del(&bsc_ctx->list);
+ memset(bsc_ctx, 0, sizeof(*bsc_ctx));
+ talloc_free(bsc_ctx);
+
+ return;
+ }
+ }
+}
diff --git a/openbsc/src/libmsc/msc_vty.c b/openbsc/src/libmsc/msc_vty.c
index b6fff56af..b9519ceeb 100644
--- a/openbsc/src/libmsc/msc_vty.c
+++ b/openbsc/src/libmsc/msc_vty.c
@@ -32,6 +32,8 @@
#include <openbsc/gsm_subscriber.h>
#include <openbsc/vlr.h>
#include <openbsc/iu.h>
+#include <openbsc/a_iface.h>
+#include <osmocom/sccp/sccp_types.h>
static struct cmd_node msc_node = {
MSC_NODE,
@@ -105,9 +107,96 @@ DEFUN(cfg_msc_no_assign_tmsi, cfg_msc_no_assign_tmsi_cmd,
return CMD_SUCCESS;
}
+DEFUN(cfg_msc_register_bsc, cfg_msc_register_bsc_cmd,
+ "bsc cs7-instance <0-15> calling-addr NAME called-addr NAME",
+ "Register a new BSC connection to this MSC.\n"
+ "Associated SS7 instance\n"
+ "SS7 instance reference number\n"
+ "Calling Address (local address of this MSC)\n"
+ "SCCP address name\n"
+ "Called Address (remote address of the BSC)\n" "SCCP address name\n")
+{
+ struct gsm_network *gsmnet = gsmnet_from_vty(vty);
+ struct osmo_sccp_addr *calling_addr;
+ struct osmo_sccp_addr *called_addr;
+ struct osmo_ss7_instance *inst;
+
+ uint32_t inst_id = atoi(argv[0]);
+ const char *calling_addr_name = argv[1];
+ const char *called_addr_name = argv[2];
+
+ 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;
+ }
+
+ calling_addr = osmo_sccp_addr_by_name(calling_addr_name, inst);
+ if (!calling_addr) {
+ vty_out(vty, "No sccp address %s found%s", calling_addr_name,
+ VTY_NEWLINE);
+ return CMD_WARNING;
+ }
+
+ called_addr = osmo_sccp_addr_by_name(called_addr_name, inst);
+ if (!called_addr) {
+ vty_out(vty, "No sccp address %s found%s", called_addr_name,
+ VTY_NEWLINE);
+ return CMD_WARNING;
+ }
+
+ a_init(gsmnet, calling_addr, called_addr, inst);
+ return CMD_SUCCESS;
+}
+
+DEFUN(cfg_msc_no_register_bsc, cfg_msc_no_register_bsc_cmd,
+ "no bsc cs7-instance <0-15> calling-addr NAME called-addr NAME",
+ NO_STR
+ "Remove a BSC connection to this MSC.\n"
+ "Associated SS7 instance\n"
+ "SS7 instance reference number\n"
+ "Calling Address (local address of this MSC)\n"
+ "SCCP address name\n"
+ "Called Address (remote address of the BSC)\n" "SCCP address name\n")
+{
+ struct osmo_sccp_addr *calling_addr;
+ struct osmo_sccp_addr *called_addr;
+ struct osmo_ss7_instance *inst;
+
+ uint32_t inst_id = atoi(argv[0]);
+ const char *calling_addr_name = argv[1];
+ const char *called_addr_name = argv[2];
+
+ 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;
+ }
+
+ calling_addr = osmo_sccp_addr_by_name(calling_addr_name, inst);
+ if (!calling_addr) {
+ vty_out(vty, "No sccp address %s found%s", calling_addr_name,
+ VTY_NEWLINE);
+ return CMD_WARNING;
+ }
+
+ called_addr = osmo_sccp_addr_by_name(called_addr_name, inst);
+ if (!called_addr) {
+ vty_out(vty, "No sccp address %s found%s", called_addr_name,
+ VTY_NEWLINE);
+ return CMD_WARNING;
+ }
+
+ a_drop(calling_addr, called_addr);
+ return CMD_SUCCESS;
+}
+
static int config_write_msc(struct vty *vty)
{
struct gsm_network *gsmnet = gsmnet_from_vty(vty);
+ struct bsc_context *bsc_ctx;
vty_out(vty, "msc%s", VTY_NEWLINE);
if (!gsmnet->auto_create_subscr)
@@ -127,6 +216,18 @@ static int config_write_msc(struct vty *vty)
mgcpgw_client_config_write(vty, " ");
iu_vty_config_write(vty, " ");
+ /* write sccp connection configuration */
+ llist_for_each_entry(bsc_ctx, &gsmnet->a.bscs, list) {
+ OSMO_ASSERT(bsc_ctx->ss7);
+ vty_out(vty,
+ " bsc cs7-instance %u calling-addr %s called-addr %s%s",
+ bsc_ctx->ss7->cfg.id,
+ osmo_sccp_name_by_addr(&bsc_ctx->calling_addr,
+ bsc_ctx->ss7),
+ osmo_sccp_name_by_addr(&bsc_ctx->called_addr,
+ bsc_ctx->ss7), VTY_NEWLINE);
+ }
+
return CMD_SUCCESS;
}
@@ -176,6 +277,9 @@ void msc_vty_init(struct gsm_network *msc_network)
install_element(MSC_NODE, &cfg_msc_no_subscr_create_cmd);
install_element(MSC_NODE, &cfg_msc_assign_tmsi_cmd);
install_element(MSC_NODE, &cfg_msc_no_assign_tmsi_cmd);
+ install_element(MSC_NODE, &cfg_msc_register_bsc_cmd);
+ install_element(MSC_NODE, &cfg_msc_no_register_bsc_cmd);
+
mgcpgw_client_vty_init(MSC_NODE, &msc_network->mgcpgw.conf);
iu_vty_init(MSC_NODE, &msc_network->iu.rab_assign_addr_enc);
}
diff --git a/openbsc/src/osmo-bsc/osmo_bsc_bssap.c b/openbsc/src/osmo-bsc/osmo_bsc_bssap.c
index afb984799..f37caa0d4 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 1f8f645ac..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,24 +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 */
- msc->msc_con->g_calling_addr.presence = OSMO_SCCP_ADDR_T_SSN | OSMO_SCCP_ADDR_T_PC;
- msc->msc_con->g_calling_addr.ssn = SCCP_SSN_BSSAP;
- msc->msc_con->g_calling_addr.ri = OSMO_SCCP_RI_SSN_PC;
- msc->msc_con->g_calling_addr.pc = 23;
- msc->msc_con->g_called_addr.presence = OSMO_SCCP_ADDR_T_SSN | OSMO_SCCP_ADDR_T_PC;
- msc->msc_con->g_called_addr.ssn = SCCP_SSN_BSSAP;
- msc->msc_con->g_called_addr.ri = OSMO_SCCP_RI_SSN_PC;
- msc->msc_con->g_called_addr.pc = 1;
- }
-
-// 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 8364d2aad..1d2a37528 100644
--- a/openbsc/src/osmo-bsc/osmo_bsc_sigtran.c
+++ b/openbsc/src/osmo-bsc/osmo_bsc_sigtran.c
@@ -88,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 */
@@ -98,8 +98,8 @@ void osmo_bsc_sigtran_tx_reset_ack(struct bsc_msc_data *msc)
struct msgb *msg;
LOGP(DMSC, LOGL_NOTICE, "Sending RESET ACK 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 */
@@ -107,7 +107,7 @@ 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;
}
@@ -186,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;
@@ -206,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);
}
@@ -233,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;
}
@@ -278,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;
}
@@ -286,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;
}
@@ -305,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;
}
@@ -314,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;
}
@@ -336,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);
@@ -385,7 +385,7 @@ void osmo_bsc_sigtran_reset(struct bsc_msc_data *msc)
gsm0808_clear(conn->conn);
/* Disconnect all Sigtran connections */
- osmo_sccp_tx_disconn(msc->msc_con->sccp_user, conn->conn_id, &msc->msc_con->g_calling_addr, 0);
+ osmo_sccp_tx_disconn(msc->a.sccp_user, conn->conn_id, &msc->a.g_calling_addr, 0);
/* Delete subscriber connection */
osmo_bsc_sigtran_del_conn(conn);
@@ -414,8 +414,6 @@ int osmo_bsc_sigtran_init(struct llist_head *mscs)
OSMO_ASSERT(mscs);
- osmo_ss7_init();
-
msc_list = mscs;
conn_id_counter = 0;
@@ -425,17 +423,14 @@ int osmo_bsc_sigtran_init(struct llist_head *mscs)
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.priv = msc;
- msc->msc_con->reset.cb = osmo_bsc_sigtran_reset_cb;
- snprintf(msc->msc_con->reset.name,sizeof(msc->msc_con->reset.name),"MSC No. %u",msc->nr);
- a_reset_start(&msc->msc_con->reset);
+ 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);
diff --git a/openbsc/src/osmo-msc/msc_main.c b/openbsc/src/osmo-msc/msc_main.c
index c79332cd3..2e225e7a4 100644
--- a/openbsc/src/osmo-msc/msc_main.c
+++ b/openbsc/src/osmo-msc/msc_main.c
@@ -503,8 +503,6 @@ TODO: we probably want some of the _net_ ctrl commands from bsc_base_ctrl_cmds_i
/* Set up IuCS */
//iu_init(tall_msc_ctx, "OsmoMSC", 1, "127.0.0.3", "127.0.0.1", 0, rcvmsg_iu_cs, rx_iu_event);
- /* Set up A interface */
- a_init(tall_msc_ctx, "OsmoMSC_A", 254, "127.0.0.3", "127.0.0.1", 0, msc_network);
if (msc_cmdline_config.daemonize) {
rc = osmo_daemonize();