diff options
Diffstat (limited to 'main/rtp.c')
-rw-r--r-- | main/rtp.c | 46 |
1 files changed, 31 insertions, 15 deletions
diff --git a/main/rtp.c b/main/rtp.c index 13c5f57cd..2273296cc 100644 --- a/main/rtp.c +++ b/main/rtp.c @@ -140,7 +140,7 @@ struct ast_rtp { char resp; unsigned int lasteventendseqn; int dtmfcount; - unsigned int dtmfduration; + unsigned int dtmfsamples; /* DTMF Transmission Variables */ unsigned int lastdigitts; char sending_digit; /* boolean - are we sending digits */ @@ -431,7 +431,7 @@ static int stun_handle_packet(int s, struct sockaddr_in *src, unsigned char *dat if (len < sizeof(struct stun_header)) { if (option_debug) - ast_log(LOG_DEBUG, "Runt STUN packet (only %d, wanting at least %d)\n", (int) len, sizeof(struct stun_header)); + ast_log(LOG_DEBUG, "Runt STUN packet (only %d, wanting at least %d)\n", (int) len, (int) sizeof(struct stun_header)); return -1; } if (stundebug) @@ -446,7 +446,7 @@ static int stun_handle_packet(int s, struct sockaddr_in *src, unsigned char *dat while(len) { if (len < sizeof(struct stun_attr)) { if (option_debug) - ast_log(LOG_DEBUG, "Runt Attribute (got %d, expecting %d)\n", (int)len, sizeof(struct stun_attr)); + ast_log(LOG_DEBUG, "Runt Attribute (got %d, expecting %d)\n", (int)len, (int) sizeof(struct stun_attr)); break; } attr = (struct stun_attr *)data; @@ -619,7 +619,7 @@ static struct ast_frame *send_dtmf(struct ast_rtp *rtp, enum ast_frame_type type if (option_debug) ast_log(LOG_DEBUG, "Ignore potential DTMF echo from '%s'\n", ast_inet_ntoa(rtp->them.sin_addr)); rtp->resp = 0; - rtp->dtmfduration = 0; + rtp->dtmfsamples = 0; return &ast_null_frame; } if (option_debug) @@ -732,14 +732,14 @@ static struct ast_frame *process_cisco_dtmf(struct ast_rtp *rtp, unsigned char * /* Why we should care on DTMF compensation at reception? */ if (!ast_test_flag(rtp, FLAG_DTMF_COMPENSATE)) { f = send_dtmf(rtp, AST_FRAME_DTMF_BEGIN); - rtp->dtmfduration = 0; + rtp->dtmfsamples = 0; } } else if ((rtp->resp == resp) && !power) { f = send_dtmf(rtp, AST_FRAME_DTMF_END); - f->samples = rtp->dtmfduration * 8; + f->samples = rtp->dtmfsamples * 8; rtp->resp = 0; } else if (rtp->resp == resp) - rtp->dtmfduration += 20 * 8; + rtp->dtmfsamples += 20 * 8; rtp->dtmfcount = dtmftimeout; return f; } @@ -759,18 +759,18 @@ static struct ast_frame *process_rfc2833(struct ast_rtp *rtp, unsigned char *dat { unsigned int event; unsigned int event_end; - unsigned int duration; + unsigned int samples; char resp = 0; struct ast_frame *f = NULL; - /* Figure out event, event end, and duration */ + /* Figure out event, event end, and samples */ event = ntohl(*((unsigned int *)(data))); event >>= 24; event_end = ntohl(*((unsigned int *)(data))); event_end <<= 8; event_end >>= 24; - duration = ntohl(*((unsigned int *)(data))); - duration &= 0xFFFF; + samples = ntohl(*((unsigned int *)(data))); + samples &= 0xFFFF; /* Print out debug if turned on */ if (rtpdebug || option_debug > 2) @@ -795,19 +795,19 @@ static struct ast_frame *process_rfc2833(struct ast_rtp *rtp, unsigned char *dat f = send_dtmf(rtp, AST_FRAME_DTMF_BEGIN); } else if (event_end & 0x80 && rtp->lasteventendseqn != seqno && rtp->resp) { f = send_dtmf(rtp, AST_FRAME_DTMF_END); - f->samples = duration; + f->len = ast_tvdiff_ms(ast_samp2tv(samples, 8000), ast_tv(0, 0)); /* XXX hard coded 8kHz */ rtp->resp = 0; rtp->lasteventendseqn = seqno; } else if (ast_test_flag(rtp, FLAG_DTMF_COMPENSATE) && event_end & 0x80 && rtp->lasteventendseqn != seqno) { rtp->resp = resp; f = send_dtmf(rtp, AST_FRAME_DTMF_END); - f->samples = duration; + f->len = ast_tvdiff_ms(ast_samp2tv(samples, 8000), ast_tv(0, 0)); /* XXX hard coded 8kHz */ rtp->resp = 0; rtp->lasteventendseqn = seqno; } rtp->dtmfcount = dtmftimeout; - rtp->dtmfduration = duration; + rtp->dtmfsamples = samples; return f; } @@ -2065,7 +2065,7 @@ void ast_rtp_reset(struct ast_rtp *rtp) rtp->lasttxformat = 0; rtp->lastrxformat = 0; rtp->dtmfcount = 0; - rtp->dtmfduration = 0; + rtp->dtmfsamples = 0; rtp->seqno = 0; rtp->rxseqno = 0; } @@ -3281,6 +3281,22 @@ enum ast_bridge_result ast_rtp_bridge(struct ast_channel *c0, struct ast_channel audio_p1_res = AST_RTP_TRY_PARTIAL; } + /* If both sides are not using the same method of DTMF transmission + * (ie: one is RFC2833, other is INFO... then we can not do direct media. + * -------------------------------------------------- + * | DTMF Mode | HAS_DTMF | Accepts Begin Frames | + * |-----------|------------|-----------------------| + * | Inband | False | True | + * | RFC2833 | True | True | + * | SIP Info | False | False | + * -------------------------------------------------- + */ + if ( (ast_test_flag(p0, FLAG_HAS_DTMF) != ast_test_flag(p1, FLAG_HAS_DTMF)) || + (!c0->tech->send_digit_begin != !c1->tech->send_digit_begin)) { + audio_p0_res = AST_RTP_TRY_PARTIAL; + audio_p1_res = AST_RTP_TRY_PARTIAL; + } + /* Get codecs from both sides */ codec0 = pr0->get_codec ? pr0->get_codec(c0) : 0; codec1 = pr1->get_codec ? pr1->get_codec(c1) : 0; |