From c3dce57d95b4f313dde62f4d607a30f5c101596c Mon Sep 17 00:00:00 2001 From: "Kevin P. Fleming" <kpfleming@digium.com> Date: Tue, 16 May 2006 22:11:02 +0000 Subject: [PATCH] mark RTP sessions that are not carrying DTMF allow native bridging of RTP sessions that are not carrying DTMF even when the bridge needs to listen to DTMF (when SIP INFO is used for DTMF, for example) git-svn-id: https://origsvn.digium.com/svn/asterisk/trunk@27559 65c4cc65-6c06-0410-ace0-fbb531ad65f3 --- channels/chan_sip.c | 7 ++++++- include/asterisk/rtp.h | 3 +++ rtp.c | 30 ++++++++++++++++++++++++++---- 3 files changed, 35 insertions(+), 5 deletions(-) diff --git a/channels/chan_sip.c b/channels/chan_sip.c index d623df5ee1..189e4f0646 100644 --- a/channels/chan_sip.c +++ b/channels/chan_sip.c @@ -2195,6 +2195,7 @@ static int create_addr_from_peer(struct sip_pvt *r, struct sip_peer *peer) ast_rtp_destroy(r->vrtp); r->vrtp = NULL; } + ast_rtp_setdtmf(r->rtp, ast_test_flag(&r->flags[0], SIP_DTMF) != SIP_DTMF_INFO); r->prefs = peer->prefs; natflags = ast_test_flag(&r->flags[0], SIP_NAT) & SIP_NAT_ROUTE; if (r->rtp) { @@ -3524,9 +3525,12 @@ static struct sip_pvt *sip_alloc(ast_string_field callid, struct sockaddr_in *si free(p); return NULL; } + ast_rtp_setdtmf(p->rtp, ast_test_flag(&p->flags[0], SIP_DTMF) != SIP_DTMF_INFO); ast_rtp_settos(p->rtp, global_tos_audio); - if (p->vrtp) + if (p->vrtp) { ast_rtp_settos(p->vrtp, global_tos_video); + ast_rtp_setdtmf(p->vrtp, 0); + } p->rtptimeout = global_rtptimeout; p->rtpholdtimeout = global_rtpholdtimeout; p->rtpkeepalive = global_rtpkeepalive; @@ -11170,6 +11174,7 @@ static int handle_request_invite(struct sip_pvt *p, struct sip_request *req, int get_rdnis(p, NULL); /* Get redirect information */ extract_uri(p, req); /* Get the Contact URI */ build_contact(p); /* Build our contact header */ + ast_rtp_setdtmf(p->rtp, ast_test_flag(&p->flags[0], SIP_DTMF) != SIP_DTMF_INFO); if (gotdest) { if (gotdest == 1 && ast_test_flag(&p->flags[1], SIP_PAGE2_ALLOWOVERLAP)) { diff --git a/include/asterisk/rtp.h b/include/asterisk/rtp.h index 7235639f16..5b03d1d861 100644 --- a/include/asterisk/rtp.h +++ b/include/asterisk/rtp.h @@ -151,6 +151,9 @@ char *ast_rtp_lookup_mime_multiple(char *buf, int size, const int capability, co void ast_rtp_setnat(struct ast_rtp *rtp, int nat); +/*! \brief Indicate whether this RTP session is carrying DTMF or not */ +void ast_rtp_setdtmf(struct ast_rtp *rtp, int dtmf); + int ast_rtp_bridge(struct ast_channel *c0, struct ast_channel *c1, int flags, struct ast_frame **fo, struct ast_channel **rc, int timeoutms); int ast_rtp_proto_register(struct ast_rtp_protocol *proto); diff --git a/rtp.c b/rtp.c index 841bbbd950..bfb2262038 100644 --- a/rtp.c +++ b/rtp.c @@ -86,6 +86,7 @@ struct rtpPayloadType { #define FLAG_NAT_ACTIVE (3 << 1) #define FLAG_NAT_INACTIVE (0 << 1) #define FLAG_NAT_INACTIVE_NOWARN (1 << 1) +#define FLAG_HAS_DTMF (1 << 3) /*! \brief RTP session description */ struct ast_rtp { @@ -434,6 +435,11 @@ void ast_rtp_setnat(struct ast_rtp *rtp, int nat) rtp->nat = nat; } +void ast_rtp_setdtmf(struct ast_rtp *rtp, int dtmf) +{ + ast_set2_flag(rtp, dtmf ? 1 : 0, FLAG_HAS_DTMF); +} + static struct ast_frame *send_dtmf(struct ast_rtp *rtp) { char iabuf[INET_ADDRSTRLEN]; @@ -1344,6 +1350,7 @@ struct ast_rtp *ast_rtp_new_with_bindaddr(struct sched_context *sched, struct io rtp->s = rtp_socket(); rtp->ssrc = ast_random(); rtp->seqno = ast_random() & 0xffff; + ast_set_flag(rtp, FLAG_HAS_DTMF); if (rtp->s < 0) { free(rtp); ast_log(LOG_ERROR, "Unable to allocate socket: %s\n", strerror(errno)); @@ -1921,10 +1928,6 @@ enum ast_bridge_result ast_rtp_bridge(struct ast_channel *c0, struct ast_channel memset(&vac0, 0, sizeof(vac0)); memset(&vac1, 0, sizeof(vac1)); - /* if need DTMF, cant native bridge */ - if (flags & (AST_BRIDGE_DTMF_CHANNEL_0 | AST_BRIDGE_DTMF_CHANNEL_1)) - return AST_BRIDGE_FAILED_NOWARN; - /* Lock channels */ ast_channel_lock(c0); while(ast_channel_trylock(c1)) { @@ -1966,6 +1969,25 @@ enum ast_bridge_result ast_rtp_bridge(struct ast_channel *c0, struct ast_channel ast_channel_unlock(c1); return AST_BRIDGE_FAILED_NOWARN; } + + if (ast_test_flag(p0, FLAG_HAS_DTMF) && (flags & AST_BRIDGE_DTMF_CHANNEL_0)) { + /* can't bridge, we are carrying DTMF for this channel and the bridge + needs it + */ + ast_channel_unlock(c0); + ast_channel_unlock(c1); + return AST_BRIDGE_FAILED_NOWARN; + } + + if (ast_test_flag(p1, FLAG_HAS_DTMF) && (flags & AST_BRIDGE_DTMF_CHANNEL_1)) { + /* can't bridge, we are carrying DTMF for this channel and the bridge + needs it + */ + ast_channel_unlock(c0); + ast_channel_unlock(c1); + return AST_BRIDGE_FAILED_NOWARN; + } + /* Get codecs from both sides */ codec0 = pr0->get_codec ? pr0->get_codec(c0) : 0; codec1 = pr1->get_codec ? pr1->get_codec(c1) : 0; -- GitLab