summaryrefslogtreecommitdiff
path: root/res/res_rtp_asterisk.c
diff options
context:
space:
mode:
Diffstat (limited to 'res/res_rtp_asterisk.c')
-rw-r--r--res/res_rtp_asterisk.c202
1 files changed, 120 insertions, 82 deletions
diff --git a/res/res_rtp_asterisk.c b/res/res_rtp_asterisk.c
index 55abf6154..f192bacb8 100644
--- a/res/res_rtp_asterisk.c
+++ b/res/res_rtp_asterisk.c
@@ -2637,10 +2637,15 @@ static int ast_rtcp_write_report(struct ast_rtp_instance *instance, int sr)
int rate = rtp_get_rate(rtp->f.subclass.format);
int ice;
int header_offset = 0;
- struct ast_sockaddr remote_address = { {0,} };
- struct ast_rtp_rtcp_report_block *report_block;
+ char *str_remote_address;
+ char *str_local_address;
+ struct ast_sockaddr remote_address = { { 0, } };
+ struct ast_sockaddr local_address = { { 0, } };
+ struct ast_sockaddr real_remote_address = { { 0, } };
+ struct ast_sockaddr real_local_address = { { 0, } };
+ struct ast_rtp_rtcp_report_block *report_block = NULL;
RAII_VAR(struct ast_rtp_rtcp_report *, rtcp_report,
- ast_rtp_rtcp_report_alloc(1),
+ ast_rtp_rtcp_report_alloc(rtp->themssrc ? 1 : 0),
ao2_cleanup);
if (!rtp || !rtp->rtcp) {
@@ -2656,16 +2661,11 @@ static int ast_rtcp_write_report(struct ast_rtp_instance *instance, int sr)
return 1;
}
- report_block = ast_calloc(1, sizeof(*report_block));
- if (!report_block) {
- return 1;
- }
-
/* Compute statistics */
calculate_lost_packet_statistics(rtp, &lost_packets, &fraction_lost);
gettimeofday(&now, NULL);
- rtcp_report->reception_report_count = 1;
+ rtcp_report->reception_report_count = rtp->themssrc ? 1 : 0;
rtcp_report->ssrc = rtp->ssrc;
rtcp_report->type = sr ? RTCP_PT_SR : RTCP_PT_RR;
if (sr) {
@@ -2674,17 +2674,25 @@ static int ast_rtcp_write_report(struct ast_rtp_instance *instance, int sr)
rtcp_report->sender_information.packet_count = rtp->txcount;
rtcp_report->sender_information.octet_count = rtp->txoctetcount;
}
- rtcp_report->report_block[0] = report_block;
- report_block->source_ssrc = rtp->themssrc;
- report_block->lost_count.fraction = (fraction_lost & 0xff);
- report_block->lost_count.packets = (lost_packets & 0xffffff);
- report_block->highest_seq_no = (rtp->cycles | (rtp->lastrxseqno & 0xffff));
- report_block->ia_jitter = (unsigned int)(rtp->rxjitter * rate);
- report_block->lsr = rtp->rtcp->themrxlsr;
- /* If we haven't received an SR report, DLSR should be 0 */
- if (!ast_tvzero(rtp->rtcp->rxlsr)) {
- timersub(&now, &rtp->rtcp->rxlsr, &dlsr);
- report_block->dlsr = (((dlsr.tv_sec * 1000) + (dlsr.tv_usec / 1000)) * 65536) / 1000;
+
+ if (rtp->themssrc) {
+ report_block = ast_calloc(1, sizeof(*report_block));
+ if (!report_block) {
+ return 1;
+ }
+
+ rtcp_report->report_block[0] = report_block;
+ report_block->source_ssrc = rtp->themssrc;
+ report_block->lost_count.fraction = (fraction_lost & 0xff);
+ report_block->lost_count.packets = (lost_packets & 0xffffff);
+ report_block->highest_seq_no = (rtp->cycles | (rtp->lastrxseqno & 0xffff));
+ report_block->ia_jitter = (unsigned int)(rtp->rxjitter * rate);
+ report_block->lsr = rtp->rtcp->themrxlsr;
+ /* If we haven't received an SR report, DLSR should be 0 */
+ if (!ast_tvzero(rtp->rtcp->rxlsr)) {
+ timersub(&now, &rtp->rtcp->rxlsr, &dlsr);
+ report_block->dlsr = (((dlsr.tv_sec * 1000) + (dlsr.tv_usec / 1000)) * 65536) / 1000;
+ }
}
timeval2ntp(rtcp_report->sender_information.ntp_timestamp, &now_msw, &now_lsw);
rtcpheader = (unsigned int *)bdata;
@@ -2699,14 +2707,17 @@ static int ast_rtcp_write_report(struct ast_rtp_instance *instance, int sr)
rtcpheader[6] = htonl(rtcp_report->sender_information.octet_count);
len += 20;
}
- rtcpheader[2 + header_offset] = htonl(report_block->source_ssrc); /* Their SSRC */
- rtcpheader[3 + header_offset] = htonl((report_block->lost_count.fraction << 24) | report_block->lost_count.packets);
- rtcpheader[4 + header_offset] = htonl(report_block->highest_seq_no);
- rtcpheader[5 + header_offset] = htonl(report_block->ia_jitter);
- rtcpheader[6 + header_offset] = htonl(report_block->lsr);
- rtcpheader[7 + header_offset] = htonl(report_block->dlsr);
- len += 24;
- rtcpheader[0] = htonl((2 << 30) | (1 << 24) | ((sr ? RTCP_PT_SR : RTCP_PT_RR) << 16) | ((len/4)-1));
+ if (report_block) {
+ rtcpheader[2 + header_offset] = htonl(report_block->source_ssrc); /* Their SSRC */
+ rtcpheader[3 + header_offset] = htonl((report_block->lost_count.fraction << 24) | report_block->lost_count.packets);
+ rtcpheader[4 + header_offset] = htonl(report_block->highest_seq_no);
+ rtcpheader[5 + header_offset] = htonl(report_block->ia_jitter);
+ rtcpheader[6 + header_offset] = htonl(report_block->lsr);
+ rtcpheader[7 + header_offset] = htonl(report_block->dlsr);
+ len += 24;
+ }
+ rtcpheader[0] = htonl((2 << 30) | (rtcp_report->reception_report_count << 24)
+ | ((sr ? RTCP_PT_SR : RTCP_PT_RR) << 16) | ((len/4)-1));
/* Insert SDES here. Probably should make SDES text equal to mimetypes[code].type (not subtype 'cos */
/* it can change mid call, and SDES can't) */
@@ -2758,8 +2769,22 @@ static int ast_rtcp_write_report(struct ast_rtp_instance *instance, int sr)
ast_verbose(" DLSR: %4.4f (sec)\n\n", (double)(report_block->dlsr / 65536.0));
}
- message_blob = ast_json_pack("{s: s}",
- "to", ast_sockaddr_stringify(&remote_address));
+ ast_rtp_instance_get_local_address(instance, &local_address);
+ if (!ast_find_ourip(&real_local_address, &local_address, 0)) {
+ str_local_address = ast_strdupa(ast_sockaddr_stringify(&real_local_address));
+ } else {
+ str_local_address = ast_strdupa(ast_sockaddr_stringify(&local_address));
+ }
+
+ if (!ast_find_ourip(&real_remote_address, &remote_address, 0)) {
+ str_remote_address = ast_strdupa(ast_sockaddr_stringify(&real_remote_address));
+ } else {
+ str_remote_address = ast_strdupa(ast_sockaddr_stringify(&remote_address));
+ }
+
+ message_blob = ast_json_pack("{s: s, s: s}",
+ "to", str_remote_address,
+ "from", str_local_address);
ast_rtp_publish_rtcp_message(instance, ast_rtp_rtcp_sent_type(),
rtcp_report,
message_blob);
@@ -3574,6 +3599,11 @@ static struct ast_frame *ast_rtcp_read(struct ast_rtp_instance *instance)
int report_counter = 0;
struct ast_rtp_rtcp_report_block *report_block;
struct ast_frame *f = &ast_null_frame;
+ char *str_local_address;
+ char *str_remote_address;
+ struct ast_sockaddr local_address = { { 0,} };
+ struct ast_sockaddr real_local_address = { { 0, } };
+ struct ast_sockaddr real_remote_address = { { 0, } };
/* Read in RTCP data from the socket */
if ((res = rtcp_recvfrom(instance, rtcpdata + AST_FRIENDLY_OFFSET,
@@ -3630,6 +3660,8 @@ static struct ast_frame *ast_rtcp_read(struct ast_rtp_instance *instance)
ast_debug(1, "Got RTCP report of %d bytes\n", res);
+ ast_rtp_instance_get_local_address(instance, &local_address);
+
while (position < packetwords) {
int i, pt, rc;
unsigned int length;
@@ -3667,11 +3699,6 @@ static struct ast_frame *ast_rtcp_read(struct ast_rtp_instance *instance)
}
i += 2; /* Advance past header and ssrc */
- if (rc == 0 && pt == RTCP_PT_RR) {
- /* We're receiving a receiver report with no reports, which is ok */
- position += (length + 1);
- continue;
- }
switch (pt) {
case RTCP_PT_SR:
gettimeofday(&rtp->rtcp->rxlsr, NULL);
@@ -3696,64 +3723,75 @@ static struct ast_frame *ast_rtcp_read(struct ast_rtp_instance *instance)
rtcp_report->sender_information.octet_count);
}
i += 5;
- if (rc < 1) {
- break;
- }
/* Intentional fall through */
case RTCP_PT_RR:
if (rtcp_report->type != RTCP_PT_SR) {
rtcp_report->type = RTCP_PT_RR;
}
- /* Don't handle multiple reception reports (rc > 1) yet */
- report_block = ast_calloc(1, sizeof(*report_block));
- if (!report_block) {
- return &ast_null_frame;
+ if (rc > 0) {
+ /* Don't handle multiple reception reports (rc > 1) yet */
+ report_block = ast_calloc(1, sizeof(*report_block));
+ if (!report_block) {
+ return &ast_null_frame;
+ }
+ rtcp_report->report_block[report_counter] = report_block;
+ report_block->source_ssrc = ntohl(rtcpheader[i]);
+ report_block->lost_count.packets = ntohl(rtcpheader[i + 1]) & 0x00ffffff;
+ report_block->lost_count.fraction = ((ntohl(rtcpheader[i + 1]) & 0xff000000) >> 24);
+ report_block->highest_seq_no = ntohl(rtcpheader[i + 2]);
+ report_block->ia_jitter = ntohl(rtcpheader[i + 3]);
+ report_block->lsr = ntohl(rtcpheader[i + 4]);
+ report_block->dlsr = ntohl(rtcpheader[i + 5]);
+ if (report_block->lsr
+ && update_rtt_stats(rtp, report_block->lsr, report_block->dlsr)
+ && rtcp_debug_test_addr(&addr)) {
+ struct timeval now;
+ unsigned int lsr_now, lsw, msw;
+ gettimeofday(&now, NULL);
+ timeval2ntp(now, &msw, &lsw);
+ lsr_now = (((msw & 0xffff) << 16) | ((lsw & 0xffff0000) >> 16));
+ ast_verbose("Internal RTCP NTP clock skew detected: "
+ "lsr=%u, now=%u, dlsr=%u (%u:%03ums), "
+ "diff=%u\n",
+ report_block->lsr, lsr_now, report_block->dlsr, report_block->dlsr / 65536,
+ (report_block->dlsr % 65536) * 1000 / 65536,
+ report_block->dlsr - (lsr_now - report_block->lsr));
+ }
+ update_jitter_stats(rtp, report_block->ia_jitter);
+ update_lost_stats(rtp, report_block->lost_count.packets);
+ rtp->rtcp->reported_jitter_count++;
+
+ if (rtcp_debug_test_addr(&addr)) {
+ ast_verbose(" Fraction lost: %d\n", report_block->lost_count.fraction);
+ ast_verbose(" Packets lost so far: %u\n", report_block->lost_count.packets);
+ ast_verbose(" Highest sequence number: %u\n", report_block->highest_seq_no & 0x0000ffff);
+ ast_verbose(" Sequence number cycles: %u\n", report_block->highest_seq_no >> 16);
+ ast_verbose(" Interarrival jitter: %u\n", report_block->ia_jitter);
+ ast_verbose(" Last SR(our NTP): %lu.%010lu\n",(unsigned long)(report_block->lsr) >> 16,((unsigned long)(report_block->lsr) << 16) * 4096);
+ ast_verbose(" DLSR: %4.4f (sec)\n",(double)report_block->dlsr / 65536.0);
+ ast_verbose(" RTT: %4.4f(sec)\n", rtp->rtcp->rtt);
+ }
+ report_counter++;
}
- rtcp_report->report_block[report_counter] = report_block;
- report_block->source_ssrc = ntohl(rtcpheader[i]);
- report_block->lost_count.packets = ntohl(rtcpheader[i + 1]) & 0x00ffffff;
- report_block->lost_count.fraction = ((ntohl(rtcpheader[i + 1]) & 0xff000000) >> 24);
- report_block->highest_seq_no = ntohl(rtcpheader[i + 2]);
- report_block->ia_jitter = ntohl(rtcpheader[i + 3]);
- report_block->lsr = ntohl(rtcpheader[i + 4]);
- report_block->dlsr = ntohl(rtcpheader[i + 5]);
- if (report_block->lsr
- && update_rtt_stats(rtp, report_block->lsr, report_block->dlsr)
- && rtcp_debug_test_addr(&addr)) {
- struct timeval now;
- unsigned int lsr_now, lsw, msw;
- gettimeofday(&now, NULL);
- timeval2ntp(now, &msw, &lsw);
- lsr_now = (((msw & 0xffff) << 16) | ((lsw & 0xffff0000) >> 16));
- ast_verbose("Internal RTCP NTP clock skew detected: "
- "lsr=%u, now=%u, dlsr=%u (%u:%03ums), "
- "diff=%u\n",
- report_block->lsr, lsr_now, report_block->dlsr, report_block->dlsr / 65536,
- (report_block->dlsr % 65536) * 1000 / 65536,
- report_block->dlsr - (lsr_now - report_block->lsr));
+ /* If and when we handle more than one report block, this should occur outside
+ * this loop.
+ */
+ if (!ast_find_ourip(&real_local_address, &local_address, 0)) {
+ str_local_address = ast_strdupa(ast_sockaddr_stringify(&real_local_address));
+ } else {
+ str_local_address = ast_strdupa(ast_sockaddr_stringify(&local_address));
}
- update_jitter_stats(rtp, report_block->ia_jitter);
- update_lost_stats(rtp, report_block->lost_count.packets);
- rtp->rtcp->reported_jitter_count++;
- if (rtcp_debug_test_addr(&addr)) {
- ast_verbose(" Fraction lost: %d\n", report_block->lost_count.fraction);
- ast_verbose(" Packets lost so far: %u\n", report_block->lost_count.packets);
- ast_verbose(" Highest sequence number: %u\n", report_block->highest_seq_no & 0x0000ffff);
- ast_verbose(" Sequence number cycles: %u\n", report_block->highest_seq_no >> 16);
- ast_verbose(" Interarrival jitter: %u\n", report_block->ia_jitter);
- ast_verbose(" Last SR(our NTP): %lu.%010lu\n",(unsigned long)(report_block->lsr) >> 16,((unsigned long)(report_block->lsr) << 16) * 4096);
- ast_verbose(" DLSR: %4.4f (sec)\n",(double)report_block->dlsr / 65536.0);
- ast_verbose(" RTT: %4.4f(sec)\n", rtp->rtcp->rtt);
+ if (!ast_find_ourip(&real_remote_address, &addr, 0)) {
+ str_remote_address = ast_strdupa(ast_sockaddr_stringify(&real_remote_address));
+ } else {
+ str_remote_address = ast_strdupa(ast_sockaddr_stringify(&addr));
}
- report_counter++;
- /* If and when we handle more than one report block, this should occur outside
- * this loop.
- */
- message_blob = ast_json_pack("{s: s, s: f}",
- "from", ast_sockaddr_stringify(&addr),
+ message_blob = ast_json_pack("{s: s, s: s, s: f}",
+ "from", str_remote_address,
+ "to", str_local_address,
"rtt", rtp->rtcp->rtt);
ast_rtp_publish_rtcp_message(instance, ast_rtp_rtcp_received_type(),
rtcp_report,