diff options
-rw-r--r-- | openbsc/include/openbsc/osmo_bsc.h | 5 | ||||
-rw-r--r-- | openbsc/include/openbsc/osmo_msc_data.h | 2 | ||||
-rw-r--r-- | openbsc/src/osmo-bsc/osmo_bsc_api.c | 12 | ||||
-rw-r--r-- | openbsc/src/osmo-bsc/osmo_bsc_msc.c | 44 | ||||
-rw-r--r-- | openbsc/src/osmo-bsc/osmo_bsc_sccp.c | 13 | ||||
-rw-r--r-- | openbsc/src/osmo-bsc/osmo_bsc_vty.c | 26 |
6 files changed, 89 insertions, 13 deletions
diff --git a/openbsc/include/openbsc/osmo_bsc.h b/openbsc/include/openbsc/osmo_bsc.h index cd4e4deb9..19b879f56 100644 --- a/openbsc/include/openbsc/osmo_bsc.h +++ b/openbsc/include/openbsc/osmo_bsc.h @@ -27,6 +27,9 @@ struct osmo_bsc_sccp_con { uint16_t cic; int rtp_port; + /* for advanced ping/pong */ + int send_ping; + /* SCCP connection realted */ struct sccp_connection *sccp; struct osmo_msc_data *msc; @@ -45,7 +48,7 @@ struct bsc_api *osmo_bsc_api(); int bsc_queue_for_msc(struct osmo_bsc_sccp_con *conn, struct msgb *msg); int bsc_open_connection(struct osmo_bsc_sccp_con *sccp, 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); int bsc_delete_connection(struct osmo_bsc_sccp_con *sccp); struct osmo_msc_data *bsc_find_msc(struct gsm_subscriber_connection *conn, struct msgb *); diff --git a/openbsc/include/openbsc/osmo_msc_data.h b/openbsc/include/openbsc/osmo_msc_data.h index 9c312ca8d..add561c0b 100644 --- a/openbsc/include/openbsc/osmo_msc_data.h +++ b/openbsc/include/openbsc/osmo_msc_data.h @@ -63,6 +63,7 @@ struct osmo_msc_data { int pong_timeout; struct osmo_timer_list ping_timer; struct osmo_timer_list pong_timer; + int advanced_ping; struct bsc_msc_connection *msc_con; int core_ncc; int core_mcc; @@ -115,6 +116,7 @@ struct osmo_bsc_data { int osmo_bsc_msc_init(struct osmo_msc_data *msc); int osmo_bsc_sccp_init(struct gsm_network *gsmnet); int msc_queue_write(struct bsc_msc_connection *conn, struct msgb *msg, int proto); +int msc_queue_write_with_ping(struct bsc_msc_connection *, struct msgb *msg, int proto); int osmo_bsc_audio_init(struct gsm_network *network); 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); |