From 49a4a643da0da08fe73b7ce7b4b37d550dc81bc2 Mon Sep 17 00:00:00 2001 From: Holger Hans Peter Freyther Date: Thu, 24 Mar 2016 21:02:36 +0100 Subject: [PATCH] mncc: Prepare alerting and and connecting the call What is not done is to actually set-up rtp that it can flow to the now confirmed remote. --- src/call.h | 13 ++++++++++++- src/mncc.c | 56 +++++++++++++++++++++++++++++++++++++++++++++++++++++- 2 files changed, 67 insertions(+), 2 deletions(-) diff --git a/src/call.h b/src/call.h index 102c366..a7f03ee 100644 --- a/src/call.h +++ b/src/call.h @@ -45,6 +45,16 @@ struct call_leg { uint32_t payload_type; uint32_t payload_msg_type; + /** + * Remote started to ring/alert + */ + void (*ring_call)(struct call_leg *); + + /** + * Remote picked up + */ + void (*connect_call)(struct call_leg *); + /** * Set by the call_leg implementation and will be called * by the application to release the call. @@ -60,7 +70,8 @@ struct sip_call_leg { enum mncc_cc_state { MNCC_CC_INITIAL, - MNCC_CC_PROCEEDING, + MNCC_CC_PROCEEDING, /* skip delivered state */ + MNCC_CC_CONNECTED, }; struct mncc_call_leg { diff --git a/src/mncc.c b/src/mncc.c index 8ce90fe..eaf6add 100644 --- a/src/mncc.c +++ b/src/mncc.c @@ -125,6 +125,30 @@ static void mncc_rtp_send(struct mncc_connection *conn, uint32_t msg_type, uint3 } } +static void mncc_call_leg_connect(struct call_leg *_leg) +{ + struct mncc_call_leg *leg; + + OSMO_ASSERT(_leg->type == CALL_TYPE_MNCC); + leg = (struct mncc_call_leg *) _leg; + + /* + * TODO.. connect rtp now.. + */ + + start_cmd_timer(leg, MNCC_SETUP_COMPL_IND); + mncc_send(leg->conn, MNCC_SETUP_RSP, leg->callref); +} + +static void mncc_call_leg_ring(struct call_leg *_leg) +{ + struct mncc_call_leg *leg; + + OSMO_ASSERT(_leg->type == CALL_TYPE_MNCC); + leg = (struct mncc_call_leg *) _leg; + + mncc_send(leg->conn, MNCC_ALERT_REQ, leg->callref); +} static void mncc_call_leg_release(struct call_leg *_leg) { @@ -148,8 +172,9 @@ static void mncc_call_leg_release(struct call_leg *_leg) call_leg_release(_leg); break; case MNCC_CC_PROCEEDING: + case MNCC_CC_CONNECTED: LOGP(DMNCC, LOGL_DEBUG, - "Releasing call in proc-state leg(%u)\n", leg->callref); + "Releasing call in non-initial 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); @@ -279,6 +304,8 @@ static void check_setup(struct mncc_connection *conn, char *buf, int rc) } leg = (struct mncc_call_leg *) call->initial; + leg->base.connect_call = mncc_call_leg_connect; + leg->base.ring_call = mncc_call_leg_ring; leg->base.release_call = mncc_call_leg_release; leg->callref = data->callref; leg->conn = conn; @@ -374,6 +401,30 @@ static void check_rel_cnf(struct mncc_connection *conn, char *buf, int rc) call_leg_release(&leg->base); } +static void check_stp_cmpl_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, "stp.cmpl call(%u) can not be found\n", + data->callref); + return; + } + + LOGP(DMNCC, LOGL_NOTICE, "leg(%u) is now connected.\n", leg->callref); + stop_cmd_timer(leg, MNCC_SETUP_COMPL_IND); + leg->state = MNCC_CC_CONNECTED; +} + static void check_hello(struct mncc_connection *conn, char *buf, int rc) { struct gsm_mncc_hello *hello; @@ -453,6 +504,9 @@ static int mncc_data(struct osmo_fd *fd, unsigned int what) case MNCC_REL_CNF: check_rel_cnf(conn, buf, rc); break; + case MNCC_SETUP_COMPL_IND: + check_stp_cmpl_ind(conn, buf, rc); + break; default: LOGP(DMNCC, LOGL_ERROR, "Unhandled message type %d/0x%x\n", msg_type, msg_type);