aboutsummaryrefslogtreecommitdiffstats
path: root/openbsc/src/nat/bsc_nat.c
diff options
context:
space:
mode:
Diffstat (limited to 'openbsc/src/nat/bsc_nat.c')
-rw-r--r--openbsc/src/nat/bsc_nat.c55
1 files changed, 55 insertions, 0 deletions
diff --git a/openbsc/src/nat/bsc_nat.c b/openbsc/src/nat/bsc_nat.c
index d9cf5e54f..ca018e0c6 100644
--- a/openbsc/src/nat/bsc_nat.c
+++ b/openbsc/src/nat/bsc_nat.c
@@ -108,6 +108,46 @@ static void send_reset_ack(struct bsc_connection *bsc)
bsc_send_data(bsc, gsm_reset_ack, sizeof(gsm_reset_ack), IPAC_PROTO_SCCP);
}
+static void send_ping(struct bsc_connection *bsc)
+{
+ static const u_int8_t id_ping[] = {
+ IPAC_MSGT_PING,
+ };
+
+ bsc_send_data(bsc, id_ping, sizeof(id_ping), IPAC_PROTO_IPACCESS);
+}
+
+static void bsc_pong_timeout(void *_bsc)
+{
+ struct bsc_connection *bsc = _bsc;
+
+ LOGP(DNAT, LOGL_ERROR, "BSC Nr: %d PONG timeout.\n", bsc->cfg->nr);
+ bsc_close_connection(bsc);
+}
+
+static void bsc_ping_timeout(void *_bsc)
+{
+ struct bsc_connection *bsc = _bsc;
+
+ send_ping(bsc);
+
+ /* send another ping in 20 seconds */
+ bsc_schedule_timer(&bsc->ping_timeout, 20, 0);
+
+ /* also start a pong timer */
+ bsc_schedule_timer(&bsc->pong_timeout, 5, 0);
+}
+
+static void start_ping_pong(struct bsc_connection *bsc)
+{
+ bsc->pong_timeout.data = bsc;
+ bsc->pong_timeout.cb = bsc_pong_timeout;
+ bsc->ping_timeout.data = bsc;
+ bsc->ping_timeout.cb = bsc_ping_timeout;
+
+ bsc_ping_timeout(bsc);
+}
+
static void send_id_ack(struct bsc_connection *bsc)
{
static const u_int8_t id_ack[] = {
@@ -437,6 +477,8 @@ void bsc_close_connection(struct bsc_connection *connection)
/* stop the timeout timer */
bsc_del_timer(&connection->id_timeout);
+ bsc_del_timer(&connection->ping_timeout);
+ bsc_del_timer(&connection->pong_timeout);
/* remove all SCCP connections */
llist_for_each_entry_safe(sccp_patch, tmp, &nat->sccp_connections, list_entry) {
@@ -490,6 +532,7 @@ static void ipaccess_auth_bsc(struct tlv_parsed *tvp, struct bsc_connection *bsc
bsc->cfg = conf;
bsc_del_timer(&bsc->id_timeout);
LOGP(DNAT, LOGL_NOTICE, "Authenticated bsc nr: %d lac: %d\n", conf->nr, conf->lac);
+ start_ping_pong(bsc);
return;
}
}
@@ -622,6 +665,18 @@ static int ipaccess_bsc_read_cb(struct bsc_fd *bfd)
LOGP(DNAT, LOGL_DEBUG, "MSG from BSC: %s proto: %d\n", hexdump(msg->data, msg->len), msg->l2h[0]);
/* Handle messages from the BSC */
+ if (bsc->authenticated) {
+ struct ipaccess_head *hh;
+ hh = (struct ipaccess_head *) msg->data;
+
+ /* stop the pong timeout */
+ if (hh->proto == IPAC_PROTO_IPACCESS && msg->l2h[0] == IPAC_MSGT_PONG) {
+ bsc_del_timer(&bsc->pong_timeout);
+ msgb_free(msg);
+ return 0;
+ }
+ }
+
/* FIXME: Currently no PONG is sent to the BSC */
/* FIXME: Currently no ID ACK is sent to the BSC */
forward_sccp_to_msc(bsc, msg);