summaryrefslogtreecommitdiffstats
path: root/openbsc/src/osmo-bsc
diff options
context:
space:
mode:
Diffstat (limited to 'openbsc/src/osmo-bsc')
-rw-r--r--openbsc/src/osmo-bsc/osmo_bsc_api.c12
-rw-r--r--openbsc/src/osmo-bsc/osmo_bsc_msc.c44
-rw-r--r--openbsc/src/osmo-bsc/osmo_bsc_sccp.c13
-rw-r--r--openbsc/src/osmo-bsc/osmo_bsc_vty.c26
4 files changed, 83 insertions, 12 deletions
diff --git a/openbsc/src/osmo-bsc/osmo_bsc_api.c b/openbsc/src/osmo-bsc/osmo_bsc_api.c
index 1751df7be..6bda3d430 100644
--- a/openbsc/src/osmo-bsc/osmo_bsc_api.c
+++ b/openbsc/src/osmo-bsc/osmo_bsc_api.c
@@ -157,13 +157,23 @@ static int bsc_compl_l3(struct gsm_subscriber_connection *conn, struct msgb *msg
static int complete_layer3(struct gsm_subscriber_connection *conn,
struct msgb *msg, struct osmo_msc_data *msc)
{
+ struct timeval tv;
struct msgb *resp;
uint16_t network_code;
uint16_t country_code;
enum bsc_con ret;
+ int send_ping = msc->advanced_ping;
+
+ /* Advanced ping/pong handling */
+ if (osmo_timer_pending(&msc->pong_timer))
+ send_ping = 0;
+ if (msc->ping_timeout == 0)
+ send_ping = 0;
+ if (send_ping && osmo_timer_remaining(&msc->ping_timer, NULL, &tv) == -1)
+ send_ping = 0;
/* allocate resource for a new connection */
- ret = bsc_create_new_connection(conn, msc);
+ ret = bsc_create_new_connection(conn, msc, send_ping);
if (ret != BSC_CON_SUCCESS) {
/* allocation has failed */
diff --git a/openbsc/src/osmo-bsc/osmo_bsc_msc.c b/openbsc/src/osmo-bsc/osmo_bsc_msc.c
index aebe84741..5f2c1c52f 100644
--- a/openbsc/src/osmo-bsc/osmo_bsc_msc.c
+++ b/openbsc/src/osmo-bsc/osmo_bsc_msc.c
@@ -1,8 +1,8 @@
/*
* Handle the connection to the MSC. This include ping/timeout/reconnect
* (C) 2008-2009 by Harald Welte <laforge@gnumonks.org>
- * (C) 2009-2011 by Holger Hans Peter Freyther <zecke@selfish.org>
- * (C) 2009-2011 by On-Waves
+ * (C) 2009-2014 by Holger Hans Peter Freyther <zecke@selfish.org>
+ * (C) 2009-2014 by On-Waves
* All Rights Reserved
*
* This program is free software; you can redistribute it and/or modify
@@ -46,6 +46,7 @@ static void initialize_if_needed(struct bsc_msc_connection *conn);
static void send_lacs(struct gsm_network *net, struct bsc_msc_connection *conn);
static void send_id_get_response(struct osmo_msc_data *data, int fd);
static void send_ping(struct osmo_msc_data *data);
+static void schedule_ping_pong(struct osmo_msc_data *data);
/*
* MGCP forwarding code
@@ -181,6 +182,29 @@ int msc_queue_write(struct bsc_msc_connection *conn, struct msgb *msg, int proto
return 0;
}
+int msc_queue_write_with_ping(struct bsc_msc_connection *conn,
+ struct msgb *msg, int proto)
+{
+ struct osmo_msc_data *data;
+ uint8_t val;
+
+ /* prepend the header */
+ ipa_prepend_header(msg, proto);
+ if (osmo_wqueue_enqueue(&conn->write_queue, msg) != 0) {
+ LOGP(DMSC, LOGL_FATAL, "Failed to queue IPA/%d\n", proto);
+ msgb_free(msg);
+ return -1;
+ }
+
+ /* add the ping as the other message */
+ val = IPAC_MSGT_PING;
+ msgb_l16tv_put(msg, 1, IPAC_PROTO_IPACCESS, &val);
+
+ data = (struct osmo_msc_data *) conn->write_queue.bfd.data;
+ schedule_ping_pong(data);
+ return 0;
+}
+
static int msc_alink_do_write(struct osmo_fd *fd, struct msgb *msg)
{
int ret;
@@ -310,6 +334,15 @@ static void send_ping(struct osmo_msc_data *data)
msc_queue_write(data->msc_con, msg, IPAC_PROTO_IPACCESS);
}
+static void schedule_ping_pong(struct osmo_msc_data *data)
+{
+ /* send another ping in 20 seconds */
+ osmo_timer_schedule(&data->ping_timer, data->ping_timeout, 0);
+
+ /* also start a pong timer */
+ osmo_timer_schedule(&data->pong_timer, data->pong_timeout, 0);
+}
+
static void msc_ping_timeout_cb(void *_data)
{
struct osmo_msc_data *data = (struct osmo_msc_data *) _data;
@@ -317,12 +350,7 @@ static void msc_ping_timeout_cb(void *_data)
return;
send_ping(data);
-
- /* send another ping in 20 seconds */
- osmo_timer_schedule(&data->ping_timer, data->ping_timeout, 0);
-
- /* also start a pong timer */
- osmo_timer_schedule(&data->pong_timer, data->pong_timeout, 0);
+ schedule_ping_pong(data);
}
static void msc_pong_timeout_cb(void *_data)
diff --git a/openbsc/src/osmo-bsc/osmo_bsc_sccp.c b/openbsc/src/osmo-bsc/osmo_bsc_sccp.c
index 3dd0a5236..33c737f52 100644
--- a/openbsc/src/osmo-bsc/osmo_bsc_sccp.c
+++ b/openbsc/src/osmo-bsc/osmo_bsc_sccp.c
@@ -1,7 +1,7 @@
/* Interaction with the SCCP subsystem */
/*
- * (C) 2009-2011 by Holger Hans Peter Freyther <zecke@selfish.org>
- * (C) 2009-2011 by On-Waves
+ * (C) 2009-2014 by Holger Hans Peter Freyther <zecke@selfish.org>
+ * (C) 2009-2014 by On-Waves
* All Rights Reserved
*
* This program is free software; you can redistribute it and/or modify
@@ -146,6 +146,11 @@ static void msc_sccp_write_ipa(struct sccp_connection *conn, struct msgb *msg,
if (conn) {
struct osmo_bsc_sccp_con *bsc_con = conn->data_ctx;
msc_con = bsc_con->msc->msc_con;
+ if (bsc_con->send_ping) {
+ bsc_con->send_ping = 0;
+ msc_queue_write_with_ping(msc_con, msg, IPAC_PROTO_SCCP);
+ return;
+ }
} else {
msc_con = ctx;
}
@@ -189,7 +194,7 @@ int bsc_queue_for_msc(struct osmo_bsc_sccp_con *conn, struct msgb *msg)
}
enum bsc_con bsc_create_new_connection(struct gsm_subscriber_connection *conn,
- struct osmo_msc_data *msc)
+ struct osmo_msc_data *msc, int send_ping)
{
struct osmo_bsc_sccp_con *bsc_con;
struct sccp_connection *sccp;
@@ -224,6 +229,8 @@ enum bsc_con bsc_create_new_connection(struct gsm_subscriber_connection *conn,
sccp->data_cb = msc_outgoing_sccp_data;
sccp->data_ctx = bsc_con;
+ bsc_con->send_ping = send_ping;
+
/* prepare the timers */
bsc_con->sccp_it_timeout.cb = sccp_it_timeout;
bsc_con->sccp_it_timeout.data = bsc_con;
diff --git a/openbsc/src/osmo-bsc/osmo_bsc_vty.c b/openbsc/src/osmo-bsc/osmo_bsc_vty.c
index eb12287d4..b1d09f35d 100644
--- a/openbsc/src/osmo-bsc/osmo_bsc_vty.c
+++ b/openbsc/src/osmo-bsc/osmo_bsc_vty.c
@@ -112,6 +112,10 @@ static void write_msc(struct vty *vty, struct osmo_msc_data *msc)
vty_out(vty, " ip.access rtp-base %d%s", msc->rtp_base, VTY_NEWLINE);
vty_out(vty, " timeout-ping %d%s", msc->ping_timeout, VTY_NEWLINE);
vty_out(vty, " timeout-pong %d%s", msc->pong_timeout, VTY_NEWLINE);
+ if (msc->advanced_ping)
+ vty_out(vty, " timeout-ping advanced%s", VTY_NEWLINE);
+ else
+ vty_out(vty, " no timeout-ping advanced%s", VTY_NEWLINE);
if (msc->ussd_welcome_txt)
vty_out(vty, " bsc-welcome-text %s%s", msc->ussd_welcome_txt, VTY_NEWLINE);
@@ -372,6 +376,26 @@ DEFUN(cfg_net_msc_pong_time,
return CMD_SUCCESS;
}
+DEFUN(cfg_net_msc_advanced_ping,
+ cfg_net_msc_advanced_ping_cmd,
+ "timeout-ping advanced",
+ "Ping timeout handling\nEnable advanced mode during SCCP\n")
+{
+ struct osmo_msc_data *data = osmo_msc_data(vty);
+ data->advanced_ping = 1;
+ return CMD_SUCCESS;
+}
+
+DEFUN(cfg_no_net_msc_advanced_ping,
+ cfg_no_net_msc_advanced_ping_cmd,
+ "no timeout-ping advanced",
+ NO_STR "Ping timeout handling\nEnable advanced mode during SCCP\n")
+{
+ struct osmo_msc_data *data = osmo_msc_data(vty);
+ data->advanced_ping = 0;
+ return CMD_SUCCESS;
+}
+
DEFUN(cfg_net_msc_welcome_ussd,
cfg_net_msc_welcome_ussd_cmd,
"bsc-welcome-text .TEXT",
@@ -719,6 +743,8 @@ int bsc_vty_init_extra(void)
install_element(MSC_NODE, &cfg_net_msc_no_dest_cmd);
install_element(MSC_NODE, &cfg_net_msc_ping_time_cmd);
install_element(MSC_NODE, &cfg_net_msc_pong_time_cmd);
+ install_element(MSC_NODE, &cfg_net_msc_advanced_ping_cmd);
+ install_element(MSC_NODE, &cfg_no_net_msc_advanced_ping_cmd);
install_element(MSC_NODE, &cfg_net_msc_welcome_ussd_cmd);
install_element(MSC_NODE, &cfg_net_msc_no_welcome_ussd_cmd);
install_element(MSC_NODE, &cfg_net_msc_lost_ussd_cmd);