From 4649746798fe3074edab720302d135c74dcf3a38 Mon Sep 17 00:00:00 2001 From: Holger Hans Peter Freyther Date: Wed, 22 Feb 2017 13:50:11 +0100 Subject: dtmf: Forward DTMF from MNCC to SIP We are not using the RTP telephony-event here but the older dtmf relay. We also only have a fixed DTMF duration for now. Change-Id: Icf770fae89f7aedf6eba9a119db9b8acc7f938df --- src/call.h | 5 +++++ src/mncc.c | 5 +++++ src/sip.c | 19 +++++++++++++++++++ 3 files changed, 29 insertions(+) (limited to 'src') diff --git a/src/call.h b/src/call.h index 7cb4932..5a11f6c 100644 --- a/src/call.h +++ b/src/call.h @@ -67,6 +67,11 @@ struct call_leg { * by the application to release the call. */ void (*release_call)(struct call_leg *); + + /** + * A DTMF key was entered. Forward it. + */ + void (*dtmf)(struct call_leg *, int keypad); }; enum sip_cc_state { diff --git a/src/mncc.c b/src/mncc.c index e96eed8..843c7e7 100644 --- a/src/mncc.c +++ b/src/mncc.c @@ -632,6 +632,7 @@ static void check_dtmf_start(struct mncc_connection *conn, char *buf, int rc) struct gsm_mncc out_mncc = { 0, }; struct gsm_mncc *data; struct mncc_call_leg *leg; + struct call_leg *other_leg; leg = find_leg(conn, buf, rc, &data); if (!leg) @@ -639,6 +640,10 @@ static void check_dtmf_start(struct mncc_connection *conn, char *buf, int rc) LOGP(DMNCC, LOGL_DEBUG, "leg(%u) DTMF key=%c\n", leg->callref, data->keypad); + other_leg = call_leg_other(&leg->base); + if (other_leg && other_leg->dtmf) + other_leg->dtmf(other_leg, data->keypad); + mncc_fill_header(&out_mncc, MNCC_START_DTMF_RSP, leg->callref); out_mncc.fields |= MNCC_F_KEYPAD; out_mncc.keypad = data->keypad; diff --git a/src/sip.c b/src/sip.c index 348f478..0a642b7 100644 --- a/src/sip.c +++ b/src/sip.c @@ -37,6 +37,7 @@ extern void *tall_mncc_ctx; static void sip_release_call(struct call_leg *_leg); static void sip_ring_call(struct call_leg *_leg); static void sip_connect_call(struct call_leg *_leg); +static void sip_dtmf_call(struct call_leg *_leg, int keypad); static void call_progress(struct sip_call_leg *leg, const sip_t *sip) { @@ -131,6 +132,7 @@ static void new_call(struct sip_agent *agent, nua_handle_t *nh, leg->base.release_call = sip_release_call; leg->base.ring_call = sip_ring_call; leg->base.connect_call = sip_connect_call; + leg->base.dtmf = sip_dtmf_call; leg->agent = agent; leg->nua_handle = nh; nua_handle_bind(nh, leg); @@ -288,6 +290,22 @@ static void sip_connect_call(struct call_leg *_leg) talloc_free(sdp); } +static void sip_dtmf_call(struct call_leg *_leg, int keypad) +{ + struct sip_call_leg *leg; + char *buf; + + OSMO_ASSERT(_leg->type == CALL_TYPE_SIP); + leg = (struct sip_call_leg *) _leg; + + buf = talloc_asprintf(leg, "Signal=%c\nDuration=160\n", keypad); + nua_info(leg->nua_handle, + NUTAG_MEDIA_ENABLE(0), + SIPTAG_CONTENT_TYPE_STR("application/dtmf-relay"), + SIPTAG_PAYLOAD_STR(buf), TAG_END()); + talloc_free(buf); +} + static int send_invite(struct sip_agent *agent, struct sip_call_leg *leg, const char *calling_num, const char *called_num) { @@ -334,6 +352,7 @@ int sip_create_remote_leg(struct sip_agent *agent, struct call *call) leg->base.type = CALL_TYPE_SIP; leg->base.call = call; leg->base.release_call = sip_release_call; + leg->base.dtmf = sip_dtmf_call; leg->agent = agent; leg->nua_handle = nua_handle(agent->nua, leg, TAG_END()); -- cgit v1.2.3