From 282da0d5d153abf8d51159aefd2c7c55fa7ee103 Mon Sep 17 00:00:00 2001 From: Holger Hans Peter Freyther Date: Thu, 24 Mar 2016 18:26:24 +0100 Subject: call/mncc: Set proceeding and deal with release based on this state Let's inform the MS that we have collected everything to move forward with the call. A new way to release the call is required in this state. --- src/call.h | 4 ++++ src/mncc.c | 42 ++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 46 insertions(+) diff --git a/src/call.h b/src/call.h index d1dbacc..dc82f97 100644 --- a/src/call.h +++ b/src/call.h @@ -5,6 +5,7 @@ #include #include +#include struct sip_agent; struct mncc_connection; @@ -34,6 +35,8 @@ struct call_leg { int type; struct call *call; + bool in_release; + /** * RTP data */ @@ -57,6 +60,7 @@ struct sip_call_leg { enum mncc_cc_state { MNCC_CC_INITIAL, + MNCC_CC_PROCEEDING, }; struct mncc_call_leg { diff --git a/src/mncc.c b/src/mncc.c index ed2d065..e10bfc3 100644 --- a/src/mncc.c +++ b/src/mncc.c @@ -146,6 +146,17 @@ static void mncc_call_leg_release(struct call_leg *_leg) mncc_send(leg->conn, MNCC_REJ_REQ, leg->callref); call_leg_release(_leg); break; + case MNCC_CC_PROCEEDING: + LOGP(DMNCC, LOGL_DEBUG, + "Releasing call in proc-state leg(%u)\n", leg->callref); + leg->base.in_release = true; + start_cmd_timer(leg, MNCC_REL_IND); + mncc_send(leg->conn, MNCC_DISC_REQ, leg->callref); + break; + default: + LOGP(DMNCC, LOGL_ERROR, "Unknown state leg(%u) state(%d)\n", + leg->callref, leg->state); + break; } } @@ -163,6 +174,10 @@ static void continue_call(struct mncc_call_leg *leg) { char *dest, *source; + /* TODO.. continue call obviously only for MO call right now */ + mncc_send(leg->conn, MNCC_CALL_PROC_REQ, leg->callref); + leg->state = MNCC_CC_PROCEEDING; + if (leg->called.type == GSM340_TYPE_INTERNATIONAL) dest = talloc_asprintf(tall_mncc_ctx, "+%.32s", leg->called.number); else @@ -279,6 +294,30 @@ static void check_setup(struct mncc_connection *conn, char *buf, int rc) mncc_rtp_send(conn, MNCC_RTP_CREATE, data->callref); } +static void check_rel_ind(struct mncc_connection *conn, char *buf, int rc) +{ + struct gsm_mncc *data; + struct mncc_call_leg *leg; + + if (rc != sizeof(*data)) { + LOGP(DMNCC, LOGL_ERROR, "gsm_mncc of wrong size %d vs. %zu\n", + rc, sizeof(*data)); + return close_connection(conn); + } + + data = (struct gsm_mncc *) buf; + leg = mncc_find_leg(data->callref); + if (!leg) { + LOGP(DMNCC, LOGL_ERROR, "rel call(%u) can not be found\n", data->callref); + return; + } + + if (leg->base.in_release) + stop_cmd_timer(leg, MNCC_REL_IND); + LOGP(DMNCC, LOGL_DEBUG, "leg(%u) was released.\n", data->callref); + call_leg_release(leg); +} + static void check_hello(struct mncc_connection *conn, char *buf, int rc) { struct gsm_mncc_hello *hello; @@ -349,6 +388,9 @@ static int mncc_data(struct osmo_fd *fd, unsigned int what) case MNCC_RTP_CREATE: check_rtp_create(conn, buf, rc); break; + case MNCC_REL_IND: + check_rel_ind(conn, buf, rc); + break; default: LOGP(DMNCC, LOGL_ERROR, "Unhandled message type %d/0x%x\n", msg_type, msg_type); -- cgit v1.2.3