summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorHolger Hans Peter Freyther <holger@moiji-mobile.com>2016-03-23 17:08:03 +0100
committerHolger Hans Peter Freyther <holger@moiji-mobile.com>2016-03-23 17:08:03 +0100
commitbc4fed27e12a08e094d8193680236f0a73796bbf (patch)
tree2412de94bbbdaaec718ffd4d83fe46623692317f
parenta0aa566ec46e98ae2b2fb35a28e252a02a6fb60d (diff)
mncc: Add a timeout when issuing a MNCC command
-rw-r--r--src/call.h4
-rw-r--r--src/mncc.c32
2 files changed, 36 insertions, 0 deletions
diff --git a/src/call.h b/src/call.h
index c1a8adc..5d50c1a 100644
--- a/src/call.h
+++ b/src/call.h
@@ -1,6 +1,7 @@
#pragma once
#include <osmocom/core/linuxlist.h>
+#include <osmocom/core/timer.h>
#include "mncc_protocol.h"
@@ -58,6 +59,9 @@ struct mncc_call_leg {
struct gsm_mncc_number calling;
char imsi[16];
+ struct osmo_timer_list cmd_timeout;
+ int rsp_wanted;
+
struct mncc_connection *conn;
};
diff --git a/src/mncc.c b/src/mncc.c
index 4f31bcc..fbbc88e 100644
--- a/src/mncc.c
+++ b/src/mncc.c
@@ -35,6 +35,36 @@
static void close_connection(struct mncc_connection *conn);
+static void cmd_timeout(void *data)
+{
+ struct mncc_call_leg *leg = data;
+
+ LOGP(DMNCC, LOGL_ERROR, "cmd(%u) never arrived for leg(%u)\n",
+ leg->rsp_wanted, leg->callref);
+ call_leg_release(&leg->base);
+}
+
+static void start_cmd_timer(struct mncc_call_leg *leg, uint32_t expected_next)
+{
+ leg->rsp_wanted = expected_next;
+
+ leg->cmd_timeout.cb = cmd_timeout;
+ leg->cmd_timeout.data = leg;
+ osmo_timer_schedule(&leg->cmd_timeout, 5, 0);
+}
+
+static void stop_cmd_timer(struct mncc_call_leg *leg, uint32_t got_res)
+{
+ if (leg->rsp_wanted != got_res) {
+ LOGP(DMNCC, LOGL_ERROR, "Wanted rsp(%u) but got(%u) for leg(%u)\n",
+ leg->rsp_wanted, got_res, leg->callref);
+ return;
+ }
+
+ LOGP(DMNCC, LOGL_DEBUG,
+ "Got response, stopping timer on leg(%u)\n", leg->callref);
+ osmo_timer_del(&leg->cmd_timeout);
+}
static struct mncc_call_leg *mncc_find_leg(uint32_t callref)
{
@@ -146,6 +176,7 @@ static void check_rtp_create(struct mncc_connection *conn, char *buf, int rc)
/* TODO.. now we can continue with the call */
LOGP(DMNCC, LOGL_DEBUG,
"RTP set-up continuing with call with leg(%u)\n", leg->callref);
+ stop_cmd_timer(leg, MNCC_RTP_CREATE);
mncc_send(leg->conn, MNCC_REJ_REQ, leg->callref);
call_leg_release(&leg->base);
}
@@ -201,6 +232,7 @@ static void check_setup(struct mncc_connection *conn, char *buf, int rc)
"Created call(%u) with MNCC leg(%u) IMSI(%.16s)\n",
call->id, leg->callref, data->imsi);
+ start_cmd_timer(leg, MNCC_RTP_CREATE);
mncc_rtp_send(conn, MNCC_RTP_CREATE, data->callref);
}