summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--CHANGES5
-rw-r--r--channels/chan_pjsip.c44
-rw-r--r--main/rtp_engine.c16
-rw-r--r--res/res_hep_rtcp.c147
-rw-r--r--res/res_rtp_asterisk.c202
5 files changed, 304 insertions, 110 deletions
diff --git a/CHANGES b/CHANGES
index a8564b845..299489e8c 100644
--- a/CHANGES
+++ b/CHANGES
@@ -245,6 +245,11 @@ res_pjsip
created for an endpoint with this setting will have its accountcode set
to the specified value.
+res_hep_rtcp
+------------------
+ * A new module, res_hep_rtcp, has been added that will forward RTCP call
+ statistics to a HEP capture server. See res_hep for more information.
+
Functions
------------------
* Function AUDIOHOOK_INHERIT has been deprecated. Audiohooks are now
diff --git a/channels/chan_pjsip.c b/channels/chan_pjsip.c
index 92a96eb0e..c958f8086 100644
--- a/channels/chan_pjsip.c
+++ b/channels/chan_pjsip.c
@@ -353,6 +353,16 @@ static struct ast_rtp_glue chan_pjsip_rtp_glue = {
.update_peer = chan_pjsip_set_rtp_peer,
};
+static void set_channel_on_rtp_instance(struct chan_pjsip_pvt *pvt, const char *channel_id)
+{
+ if (pvt->media[SIP_MEDIA_AUDIO] && pvt->media[SIP_MEDIA_AUDIO]->rtp) {
+ ast_rtp_instance_set_channel_id(pvt->media[SIP_MEDIA_AUDIO]->rtp, channel_id);
+ }
+ if (pvt->media[SIP_MEDIA_VIDEO] && pvt->media[SIP_MEDIA_VIDEO]->rtp) {
+ ast_rtp_instance_set_channel_id(pvt->media[SIP_MEDIA_VIDEO]->rtp, channel_id);
+ }
+}
+
/*! \brief Function called to create a new PJSIP Asterisk channel */
static struct ast_channel *chan_pjsip_new(struct ast_sip_session *session, int state, const char *exten, const char *title, const struct ast_assigned_ids *assignedids, const struct ast_channel *requestor, const char *cid_name)
{
@@ -452,12 +462,7 @@ static struct ast_channel *chan_pjsip_new(struct ast_sip_session *session, int s
* these will need to be recaptured as well */
pvt->media[SIP_MEDIA_AUDIO] = ao2_find(session->media, "audio", OBJ_KEY);
pvt->media[SIP_MEDIA_VIDEO] = ao2_find(session->media, "video", OBJ_KEY);
- if (pvt->media[SIP_MEDIA_AUDIO] && pvt->media[SIP_MEDIA_AUDIO]->rtp) {
- ast_rtp_instance_set_channel_id(pvt->media[SIP_MEDIA_AUDIO]->rtp, ast_channel_uniqueid(chan));
- }
- if (pvt->media[SIP_MEDIA_VIDEO] && pvt->media[SIP_MEDIA_VIDEO]->rtp) {
- ast_rtp_instance_set_channel_id(pvt->media[SIP_MEDIA_VIDEO]->rtp, ast_channel_uniqueid(chan));
- }
+ set_channel_on_rtp_instance(pvt, ast_channel_uniqueid(chan));
return chan;
}
@@ -685,12 +690,7 @@ static int fixup(void *data)
struct chan_pjsip_pvt *pvt = channel->pvt;
channel->session->channel = fix_data->chan;
- if (pvt->media[SIP_MEDIA_AUDIO] && pvt->media[SIP_MEDIA_AUDIO]->rtp) {
- ast_rtp_instance_set_channel_id(pvt->media[SIP_MEDIA_AUDIO]->rtp, ast_channel_uniqueid(fix_data->chan));
- }
- if (pvt->media[SIP_MEDIA_VIDEO] && pvt->media[SIP_MEDIA_VIDEO]->rtp) {
- ast_rtp_instance_set_channel_id(pvt->media[SIP_MEDIA_VIDEO]->rtp, ast_channel_uniqueid(fix_data->chan));
- }
+ set_channel_on_rtp_instance(pvt, ast_channel_uniqueid(fix_data->chan));
return 0;
}
@@ -1523,7 +1523,9 @@ static void update_initial_connected_line(struct ast_sip_session *session)
static int call(void *data)
{
- struct ast_sip_session *session = data;
+ struct ast_sip_channel_pvt *channel = data;
+ struct ast_sip_session *session = channel->session;
+ struct chan_pjsip_pvt *pvt = channel->pvt;
pjsip_tx_data *tdata;
int res = ast_sip_session_create_invite(session, &tdata);
@@ -1532,10 +1534,11 @@ static int call(void *data)
ast_set_hangupsource(session->channel, ast_channel_name(session->channel), 0);
ast_queue_hangup(session->channel);
} else {
+ set_channel_on_rtp_instance(pvt, ast_channel_uniqueid(session->channel));
update_initial_connected_line(session);
ast_sip_session_send_request(session, tdata);
}
- ao2_ref(session, -1);
+ ao2_ref(channel, -1);
return res;
}
@@ -1544,10 +1547,10 @@ static int chan_pjsip_call(struct ast_channel *ast, const char *dest, int timeou
{
struct ast_sip_channel_pvt *channel = ast_channel_tech_pvt(ast);
- ao2_ref(channel->session, +1);
- if (ast_sip_push_task(channel->session->serializer, call, channel->session)) {
+ ao2_ref(channel, +1);
+ if (ast_sip_push_task(channel->session->serializer, call, channel)) {
ast_log(LOG_WARNING, "Error attempting to place outbound call to call '%s'\n", dest);
- ao2_cleanup(channel->session);
+ ao2_cleanup(channel);
return -1;
}
@@ -1632,12 +1635,7 @@ static struct hangup_data *hangup_data_alloc(int cause, struct ast_channel *chan
static void clear_session_and_channel(struct ast_sip_session *session, struct ast_channel *ast, struct chan_pjsip_pvt *pvt)
{
session->channel = NULL;
- if (pvt->media[SIP_MEDIA_AUDIO] && pvt->media[SIP_MEDIA_AUDIO]->rtp) {
- ast_rtp_instance_set_channel_id(pvt->media[SIP_MEDIA_AUDIO]->rtp, "");
- }
- if (pvt->media[SIP_MEDIA_VIDEO] && pvt->media[SIP_MEDIA_VIDEO]->rtp) {
- ast_rtp_instance_set_channel_id(pvt->media[SIP_MEDIA_VIDEO]->rtp, "");
- }
+ set_channel_on_rtp_instance(pvt, "");
ast_channel_tech_pvt_set(ast, NULL);
}
diff --git a/main/rtp_engine.c b/main/rtp_engine.c
index 07ef1f697..52be8b90e 100644
--- a/main/rtp_engine.c
+++ b/main/rtp_engine.c
@@ -1909,13 +1909,15 @@ static struct ast_json *rtcp_report_to_json(struct stasis_message *msg,
for (i = 0; i < payload->report->reception_report_count; i++) {
struct ast_json *json_report_block;
- json_report_block = ast_json_pack("{s: i, s: i, s: i, s: i, s: i, s: i, s: i}",
+ char str_lsr[32];
+ snprintf(str_lsr, sizeof(str_lsr), "%u", payload->report->report_block[i]->lsr);
+ json_report_block = ast_json_pack("{s: i, s: i, s: i, s: i, s: i, s: s, s: i}",
"source_ssrc", payload->report->report_block[i]->source_ssrc,
"fraction_lost", payload->report->report_block[i]->lost_count.fraction,
"packets_lost", payload->report->report_block[i]->lost_count.packets,
"highest_seq_no", payload->report->report_block[i]->highest_seq_no,
"ia_jitter", payload->report->report_block[i]->ia_jitter,
- "lsr", payload->report->report_block[i]->lsr,
+ "lsr", str_lsr,
"dlsr", payload->report->report_block[i]->dlsr);
if (!json_report_block) {
return NULL;
@@ -1927,9 +1929,13 @@ static struct ast_json *rtcp_report_to_json(struct stasis_message *msg,
}
if (payload->report->type == AST_RTP_RTCP_SR) {
- json_rtcp_sender_info = ast_json_pack("{s: i, s: i, s: i, s: i, s: i}",
- "ntp_timestamp_sec", payload->report->sender_information.ntp_timestamp.tv_sec,
- "ntp_timestamp_usec", payload->report->sender_information.ntp_timestamp.tv_usec,
+ char sec[32];
+ char usec[32];
+ snprintf(sec, sizeof(sec), "%ld", payload->report->sender_information.ntp_timestamp.tv_sec);
+ snprintf(usec, sizeof(usec), "%ld", payload->report->sender_information.ntp_timestamp.tv_usec);
+ json_rtcp_sender_info = ast_json_pack("{s: s, s: s, s: i, s: i, s: i}",
+ "ntp_timestamp_sec", sec,
+ "ntp_timestamp_usec", usec,
"rtp_timestamp", payload->report->sender_information.rtp_timestamp,
"packets", payload->report->sender_information.packet_count,
"octets", payload->report->sender_information.octet_count);
diff --git a/res/res_hep_rtcp.c b/res/res_hep_rtcp.c
new file mode 100644
index 000000000..63df1c8b0
--- /dev/null
+++ b/res/res_hep_rtcp.c
@@ -0,0 +1,147 @@
+/*
+ * Asterisk -- An open source telephony toolkit.
+ *
+ * Copyright (C) 1999 - 2014, Digium, Inc.
+ *
+ * Matt Jordan <mjordan@digium.com>
+ *
+ * See http://www.asterisk.org for more information about
+ * the Asterisk project. Please do not directly contact
+ * any of the maintainers of this project for assistance;
+ * the project provides a web site, mailing lists and IRC
+ * channels for your use.
+ *
+ * This program is free software, distributed under the terms of
+ * the GNU General Public License Version 2. See the LICENSE file
+ * at the top of the source tree.
+ */
+
+/*!
+ * \file
+ * \brief RTCP logging with Homer
+ *
+ * \author Matt Jordan <mjordan@digium.com>
+ *
+ */
+
+/*** MODULEINFO
+ <depend>res_hep</depend>
+ <defaultenabled>no</defaultenabled>
+ <support_level>extended</support_level>
+ ***/
+
+#include "asterisk.h"
+
+ASTERISK_FILE_VERSION(__FILE__, "$Revision$")
+
+#include <pjsip.h>
+
+#include "asterisk/res_hep.h"
+#include "asterisk/module.h"
+#include "asterisk/netsock2.h"
+#include "asterisk/stasis.h"
+#include "asterisk/rtp_engine.h"
+#include "asterisk/json.h"
+#include "asterisk/config.h"
+
+static struct stasis_subscription *stasis_rtp_subscription;
+
+static void rtcp_message_handler(struct stasis_message *message)
+{
+
+ RAII_VAR(struct ast_json *, json_payload, NULL, ast_json_unref);
+ RAII_VAR(char *, payload, NULL, ast_json_free);
+ struct ast_json *json_blob;
+ struct ast_json *json_channel;
+ struct ast_json *json_rtcp;
+ struct hepv3_capture_info *capture_info;
+ struct ast_json *from;
+ struct ast_json *to;
+ struct timeval current_time = ast_tvnow();
+
+ json_payload = stasis_message_to_json(message, NULL);
+ if (!json_payload) {
+ return;
+ }
+
+ json_blob = ast_json_object_get(json_payload, "blob");
+ if (!json_blob) {
+ return;
+ }
+
+ json_channel = ast_json_object_get(json_payload, "channel");
+ if (!json_channel) {
+ return;
+ }
+
+ json_rtcp = ast_json_object_get(json_payload, "rtcp_report");
+ if (!json_rtcp) {
+ return;
+ }
+
+ from = ast_json_object_get(json_blob, "from");
+ to = ast_json_object_get(json_blob, "to");
+ if (!from || !to) {
+ return;
+ }
+
+ payload = ast_json_dump_string(json_rtcp);
+ if (ast_strlen_zero(payload)) {
+ return;
+ }
+
+ capture_info = hepv3_create_capture_info(payload, strlen(payload));
+ if (!capture_info) {
+ return;
+ }
+ ast_sockaddr_parse(&capture_info->src_addr, ast_json_string_get(from), PARSE_PORT_REQUIRE);
+ ast_sockaddr_parse(&capture_info->dst_addr, ast_json_string_get(to), PARSE_PORT_REQUIRE);
+
+ capture_info->uuid = ast_strdup(ast_json_string_get(ast_json_object_get(json_channel, "name")));
+ if (!capture_info->uuid) {
+ ao2_ref(capture_info, -1);
+ return;
+ }
+ capture_info->capture_time = current_time;
+ capture_info->capture_type = HEPV3_CAPTURE_TYPE_RTCP;
+ capture_info->zipped = 0;
+
+ hepv3_send_packet(capture_info);
+}
+
+static void rtp_topic_handler(void *data, struct stasis_subscription *sub, struct stasis_message *message)
+{
+ struct stasis_message_type *message_type = stasis_message_type(message);
+
+ if ((message_type == ast_rtp_rtcp_sent_type()) ||
+ (message_type == ast_rtp_rtcp_received_type())) {
+ rtcp_message_handler(message);
+ }
+}
+
+static int load_module(void)
+{
+
+ stasis_rtp_subscription = stasis_subscribe(ast_rtp_topic(),
+ rtp_topic_handler, NULL);
+ if (!stasis_rtp_subscription) {
+ return AST_MODULE_LOAD_FAILURE;
+ }
+
+ return AST_MODULE_LOAD_SUCCESS;
+}
+
+static int unload_module(void)
+{
+ if (stasis_rtp_subscription) {
+ stasis_rtp_subscription = stasis_unsubscribe(stasis_rtp_subscription);
+ }
+
+ return 0;
+}
+
+AST_MODULE_INFO(ASTERISK_GPL_KEY, AST_MODFLAG_LOAD_ORDER, "RTCP HEPv3 Logger",
+ .load = load_module,
+ .unload = unload_module,
+ .load_pri = AST_MODPRI_DEFAULT,
+ );
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,