[asterisk-commits] mjordan: branch group/pinefrog-rtcp-trunk r385680 - in /team/group/pinefrog-r...

SVN commits to the Asterisk project asterisk-commits at lists.digium.com
Sun Apr 14 19:58:52 CDT 2013


Author: mjordan
Date: Sun Apr 14 19:58:50 2013
New Revision: 385680

URL: http://svnview.digium.com/svn/asterisk?view=rev&rev=385680
Log:
Merge oej's pinefrog-rtcp-11 branch to trunk

Added:
    team/group/pinefrog-rtcp-trunk/
      - copied from r385638, trunk/
    team/group/pinefrog-rtcp-trunk/channels/sip/include/rtcp.h   (with props)
    team/group/pinefrog-rtcp-trunk/channels/sip/rtcp.c   (with props)
Modified:
    team/group/pinefrog-rtcp-trunk/CREDITS
    team/group/pinefrog-rtcp-trunk/channels/chan_sip.c
    team/group/pinefrog-rtcp-trunk/channels/sip/dialplan_functions.c
    team/group/pinefrog-rtcp-trunk/channels/sip/include/sip.h
    team/group/pinefrog-rtcp-trunk/contrib/realtime/mysql/sippeers.sql
    team/group/pinefrog-rtcp-trunk/contrib/realtime/postgresql/realtime.sql
    team/group/pinefrog-rtcp-trunk/include/asterisk/logger.h
    team/group/pinefrog-rtcp-trunk/include/asterisk/rtp_engine.h
    team/group/pinefrog-rtcp-trunk/main/logger.c
    team/group/pinefrog-rtcp-trunk/main/rtp_engine.c
    team/group/pinefrog-rtcp-trunk/res/res_rtp_asterisk.c

Modified: team/group/pinefrog-rtcp-trunk/CREDITS
URL: http://svnview.digium.com/svn/asterisk/team/group/pinefrog-rtcp-trunk/CREDITS?view=diff&rev=385680&r1=385638&r2=385680
==============================================================================
--- team/group/pinefrog-rtcp-trunk/CREDITS (original)
+++ team/group/pinefrog-rtcp-trunk/CREDITS Sun Apr 14 19:58:50 2013
@@ -39,6 +39,9 @@
 	* Voop AS, Nuvio Inc, Inotel S.A and Foniris Telecom A/S - funding for
 		rewrite of SIP transfers
 
+
+Nordicom Norge AS, Kristiansand, Norway, for funding work with RTCP support
+and Call Quality Records.
 
 === WISHLIST CONTRIBUTERS ===
 
@@ -153,6 +156,7 @@
 		transfer support, SIP presence support, SIP call state updates
 		(dialog-info), QUEUE_EXISTS function, device state provider
 		architecture, multiparking (together with mvanbaak), meetme and
+		RTCP improvements, Call Quality Records,
 		parking device states, MiniVM - the small voicemail system,
 		many documentation updates/corrections, and many bug fixes.
 		oej(AT)edvina.net, http://edvina.net
@@ -265,8 +269,8 @@
 		implementation Developers: Marc Blanchet, Simon Perreault and 
 		Jean-Philippe Dionne
 
-	* ClearIT AB, Sweden - res_mutestream, queue_exists and various other
-		patches (developed by oej)
+	* ClearIT AB, Sweden - res_mutestream, queue_exists, RTCP improvements
+		and various other patches (developed by oej)
 
 	* Despegar.com, Argentina - AstData API implementation, also sponsored
 		by Google as part of the gsoc/2009 program (developed by Eliel)

Modified: team/group/pinefrog-rtcp-trunk/channels/chan_sip.c
URL: http://svnview.digium.com/svn/asterisk/team/group/pinefrog-rtcp-trunk/channels/chan_sip.c?view=diff&rev=385680&r1=385638&r2=385680
==============================================================================
--- team/group/pinefrog-rtcp-trunk/channels/chan_sip.c (original)
+++ team/group/pinefrog-rtcp-trunk/channels/chan_sip.c Sun Apr 14 19:58:50 2013
@@ -293,6 +293,7 @@
 #include "sip/include/dialog.h"
 #include "sip/include/dialplan_functions.h"
 #include "sip/include/security_events.h"
+#include "sip/include/rtcp.h"
 #include "asterisk/sip_api.h"
 #include "asterisk/app.h"
 
@@ -740,7 +741,6 @@
 	{ AST_REDIRECTING_REASON_SEND_TO_VM, "send_to_vm"},
 };
 
-
 /*! \name DefaultSettings
 	Default setttings are used as a channel setting and as a default when
 	configuring devices
@@ -6618,6 +6618,22 @@
 
 	if (dumphistory)
 		sip_dump_history(p);
+
+	AST_SCHED_DEL(sched, p->rtcpeventid);
+
+ 	if (p->audioqual) {
+ 		/* We have a quality report to write to realtime before we leave this world. */
+ 		qos_write_realtime(p, p->audioqual);
+ 		free(p->audioqual);
+ 		p->audioqual = NULL;
+ 	}
+ 	if (p->videoqual) {
+ 		/* We have a quality report to write to realtime before we leave this world. */
+ 		qos_write_realtime(p, p->videoqual);
+ 		free(p->videoqual);
+ 		p->videoqual = NULL;
+ 	}
+
 
 	if (p->options) {
 		if (p->options->outboundproxy) {
@@ -7368,6 +7384,7 @@
 		ast_rtp_instance_update_source(p->rtp);
 		res = transmit_response_with_sdp(p, "200 OK", &p->initreq, XMIT_CRITICAL, FALSE, TRUE);
 		ast_set_flag(&p->flags[1], SIP_PAGE2_DIALOG_ESTABLISHED);
+		start_rtcp_events(p, sched);
 	}
 	sip_pvt_unlock(p);
 	return res;
@@ -8774,8 +8791,10 @@
 		set_socket_transport(&p->socket, SIP_TRANSPORT_UDP);
 	}
 
+	p->sip_cfg = &sip_cfg;
 	p->socket.fd = -1;
 	p->method = intended_method;
+	p->rtcpeventid = -1;
 	p->initid = -1;
 	p->waitid = -1;
 	p->reinviteid = -1;
@@ -8837,6 +8856,14 @@
 		build_callid_pvt(p);
 	else
 		ast_string_field_set(p, callid, callid);
+
+	/* Set cnames for the RTCP SDES */
+	if (p->rtp) {
+		ast_rtp_instance_setcname(p->rtp, p->callid, strlen(p->callid));
+	}
+	if (p->vrtp) {
+		ast_rtp_instance_setcname(p->vrtp, p->callid, strlen(p->callid));
+	}
 	/* Assign default music on hold class */
 	ast_string_field_set(p, mohinterpret, default_mohinterpret);
 	ast_string_field_set(p, mohsuggest, default_mohsuggest);
@@ -9879,6 +9906,7 @@
 			      ast_channel_uniqueid(dialog->owner));
 	append_history(dialog, holdstate ? "Hold" : "Unhold", "%s", ast_str_buffer(req->data));
 	if (!holdstate) {	/* Put off remote hold */
+		ast_rtp_instance_hold(dialog->rtp, 0);	/* Turn off RTP hold */
 		ast_clear_flag(&dialog->flags[1], SIP_PAGE2_CALL_ONHOLD);	/* Clear both flags */
 		return;
 	}
@@ -10794,9 +10822,9 @@
 				       S_OR(p->mohsuggest, NULL),
 				       !ast_strlen_zero(p->mohsuggest) ? strlen(p->mohsuggest) + 1 : 0);
 		}
-		if (sendonly)
-			ast_rtp_instance_stop(p->rtp);
-		/* RTCP needs to go ahead, even if we're on hold!!! */
+		if (sendonly == 1 || sendonly == 2) {	/* sendonly (from the other side) or inactive */
+			ast_rtp_instance_hold(p->rtp, 1);
+		}
 		/* Activate a re-invite */
 		ast_queue_frame(p->owner, &ast_null_frame);
 		change_hold_state(p, req, TRUE, sendonly);
@@ -20765,9 +20793,11 @@
 {
 	int realtimepeers;
 	int realtimeregs;
+	int realtimertpqos;
 	char codec_buf[SIPBUFSIZE];
 	const char *msg;	/* temporary msg pointer */
 	struct sip_auth_container *credentials;
+
 
 	switch (cmd) {
 	case CLI_INIT:
@@ -20785,6 +20815,7 @@
 
 	realtimepeers = ast_check_realtime("sippeers");
 	realtimeregs = ast_check_realtime("sipregs");
+	realtimertpqos = ast_check_realtime("rtpcqr");
 
 	ast_mutex_lock(&authl_lock);
 	credentials = authl;
@@ -20858,6 +20889,8 @@
 	}
 	ast_cli(a->fd, "  Record SIP history:     %s\n", AST_CLI_ONOFF(recordhistory));
 	ast_cli(a->fd, "  Call Events:            %s\n", AST_CLI_ONOFF(sip_cfg.callevents));
+	ast_cli(a->fd, "  RTCP Events:            %s\n", AST_CLI_ONOFF(sip_cfg.rtcpevents));
+	ast_cli(a->fd, "  RTCP Event timer:       %d\n", sip_cfg.rtcptimer);
 	ast_cli(a->fd, "  Auth. Failure Events:   %s\n", AST_CLI_ONOFF(global_authfailureevents));
 
 	ast_cli(a->fd, "  T.38 support:           %s\n", AST_CLI_YESNO(ast_test_flag(&global_flags[1], SIP_PAGE2_T38SUPPORT)));
@@ -20867,6 +20900,7 @@
 		ast_cli(a->fd, "  SIP realtime:           Disabled\n" );
 	else
 		ast_cli(a->fd, "  SIP realtime:           Enabled\n" );
+	ast_cli(a->fd, "  QoS realtime reports:   %s\n", realtimertpqos ? "Enabled" : "Disabled" );
 	ast_cli(a->fd, "  Qualify Freq :          %d ms\n", global_qualifyfreq);
 	ast_cli(a->fd, "  Q.850 Reason header:    %s\n", AST_CLI_YESNO(ast_test_flag(&global_flags[1], SIP_PAGE2_Q850_REASON)));
 	ast_cli(a->fd, "  Store SIP_CAUSE:        %s\n", AST_CLI_YESNO(global_store_sip_cause));
@@ -22893,6 +22927,7 @@
 			ast_log(LOG_WARNING, "Unable to cancel SIP destruction.  Expect bad things.\n");
 		}
 		check_pendings(p);
+		start_rtcp_events(p, sched);
 		break;
 
 	case 180:	/* 180 Ringing */
@@ -23180,6 +23215,7 @@
 		ast_set_flag(&p->flags[1], SIP_PAGE2_DIALOG_ESTABLISHED);
 		xmitres = transmit_request(p, SIP_ACK, seqno, XMIT_UNRELIABLE, TRUE);
 		check_pendings(p);
+		start_rtcp_events(p, sched);
 		break;
 
 	case 407: /* Proxy authentication */
@@ -23911,16 +23947,21 @@
 	}
 }
 
-/*! \brief Immediately stop RTP, VRTP and UDPTL as applicable */
+/*! \brief Immediately stop RTP, VRTP, TEXT and UDPTL as applicable */
 static void stop_media_flows(struct sip_pvt *p)
 {
 	/* Immediately stop RTP, VRTP and UDPTL as applicable */
-	if (p->rtp)
+	if (p->rtp && !ast_rtp_instance_isactive(p->rtp)) {
+		sip_rtcp_report(p, p->rtp, SDP_AUDIO, TRUE);
 		ast_rtp_instance_stop(p->rtp);
-	if (p->vrtp)
+	}
+	if (p->vrtp && !ast_rtp_instance_isactive(p->vrtp)) {
+		sip_rtcp_report(p, p->vrtp, SDP_VIDEO, TRUE);
 		ast_rtp_instance_stop(p->vrtp);
-	if (p->trtp)
+	}
+	if (p->trtp && !ast_rtp_instance_isactive(p->trtp)) {
 		ast_rtp_instance_stop(p->trtp);
+	}
 	if (p->udptl)
 		ast_udptl_stop(p->udptl);
 }
@@ -26912,6 +26953,7 @@
 
 
 		if (p->rtp && (quality = ast_rtp_instance_get_quality(p->rtp, AST_RTP_INSTANCE_STAT_FIELD_QUALITY, quality_buf, sizeof(quality_buf)))) {
+			sip_rtcp_report(p, p->rtp, SDP_AUDIO, TRUE);
 			if (p->do_history) {
 				append_history(p, "RTCPaudio", "Quality:%s", quality);
 
@@ -26942,6 +26984,7 @@
 		}
 
 		if (p->vrtp && (quality = ast_rtp_instance_get_quality(p->vrtp, AST_RTP_INSTANCE_STAT_FIELD_QUALITY, quality_buf, sizeof(quality_buf)))) {
+			sip_rtcp_report(p, p->rtp, SDP_VIDEO, TRUE);
 			if (p->do_history) {
 				append_history(p, "RTCPvideo", "Quality:%s", quality);
 			}
@@ -31696,6 +31739,8 @@
 	/* Misc settings for the channel */
 	global_relaxdtmf = FALSE;
 	sip_cfg.callevents = DEFAULT_CALLEVENTS;
+	sip_cfg.rtcpevents = FALSE;
+	sip_cfg.rtcptimer = 0;	/* Only report at end of call (default) */
 	global_authfailureevents = FALSE;
 	global_t1 = DEFAULT_TIMER_T1;
 	global_timer_b = 64 * DEFAULT_TIMER_T1;
@@ -32175,6 +32220,13 @@
 			} else {
 				ast_log(LOG_WARNING, "Invalid qualifyfreq number '%s' at line %d of %s\n", v->value, v->lineno, config);
 				global_qualifyfreq = DEFAULT_QUALIFYFREQ;
+			}
+		} else if (!strcasecmp(v->name, "rtcpevents")) {
+			sip_cfg.rtcpevents = ast_true(v->value);
+		} else if (!strcasecmp(v->name, "rtcpeventtimer")) {
+			if (sscanf(v->value, "%30d", &sip_cfg.rtcptimer) != 1) {
+				ast_log(LOG_WARNING, "RTCP event timer needs to be value (seconds between reports) at line %d of sip.conf\n", v->lineno);
+				sip_cfg.rtcptimer = 0;
 			}
 		} else if (!strcasecmp(v->name, "callevents")) {
 			sip_cfg.callevents = ast_true(v->value);

Modified: team/group/pinefrog-rtcp-trunk/channels/sip/dialplan_functions.c
URL: http://svnview.digium.com/svn/asterisk/team/group/pinefrog-rtcp-trunk/channels/sip/dialplan_functions.c?view=diff&rev=385680&r1=385638&r2=385680
==============================================================================
--- team/group/pinefrog-rtcp-trunk/channels/sip/dialplan_functions.c (original)
+++ team/group/pinefrog-rtcp-trunk/channels/sip/dialplan_functions.c Sun Apr 14 19:58:50 2013
@@ -162,6 +162,11 @@
 			if (!ast_rtp_instance_get_quality(rtp, AST_RTP_INSTANCE_STAT_FIELD_QUALITY, quality_buf, sizeof(quality_buf))) {
 				return -1;
 			}
+#ifdef OEJ
+			if (!ast_rtp_instance_get_qualdata(rtp, ???, &qos)) {
+				this_needs_some_love;
+			}
+#endif
 
 			ast_copy_string(buf, quality_buf, buflen);
 			return res;

Added: team/group/pinefrog-rtcp-trunk/channels/sip/include/rtcp.h
URL: http://svnview.digium.com/svn/asterisk/team/group/pinefrog-rtcp-trunk/channels/sip/include/rtcp.h?view=auto&rev=385680
==============================================================================
--- team/group/pinefrog-rtcp-trunk/channels/sip/include/rtcp.h (added)
+++ team/group/pinefrog-rtcp-trunk/channels/sip/include/rtcp.h Sun Apr 14 19:58:50 2013
@@ -1,0 +1,50 @@
+/*
+ * Asterisk -- An open source telephony toolkit.
+ *
+ * Copyright (C) 2013 Olle E. Johansson, Edvina AB
+ *
+ * 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 rtcp.h
+ *
+ * \brief RTCP additional functions
+ *
+ * \author Olle E. Johansson <oej at edvina.net>
+ */
+
+#include "asterisk.h"
+
+#include "asterisk/utils.h"
+#include "asterisk/rtp_engine.h"
+#include "sip.h"
+
+#ifndef _SIP_RTCP_H
+#define _SIP_RTCP_H
+
+/*! \brief Set various data items in the RTP structure, like channel identifier.
+ */
+void sip_rtcp_set_data(struct sip_pvt *dialog, struct ast_rtp_instance *instance, enum media_type type);
+
+int send_rtcp_events(const void *data);
+void start_rtcp_events(struct sip_pvt *dialog, struct ast_sched_context *sched);
+/*
+# For 1.4:
+# static void sip_rtcp_report(struct sip_pvt *p, struct ast_rtp *rtp, enum media_type type, int reporttype);
+*/
+
+void sip_rtcp_report(struct sip_pvt *dialog, struct ast_rtp_instance *instance, enum media_type type, int reporttype);
+//void qos_write_realtime(struct sip_pvt *dialog, struct ast_rtp_quality *qual);
+void qos_write_realtime(struct sip_pvt *dialog, struct ast_rtp_instance_stats *qual);
+
+
+
+#endif /* _SIP_RTCP_H */

Propchange: team/group/pinefrog-rtcp-trunk/channels/sip/include/rtcp.h
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: team/group/pinefrog-rtcp-trunk/channels/sip/include/rtcp.h
------------------------------------------------------------------------------
    svn:keywords = Author Date Id Revision

Propchange: team/group/pinefrog-rtcp-trunk/channels/sip/include/rtcp.h
------------------------------------------------------------------------------
    svn:mime-type = text/plain

Modified: team/group/pinefrog-rtcp-trunk/channels/sip/include/sip.h
URL: http://svnview.digium.com/svn/asterisk/team/group/pinefrog-rtcp-trunk/channels/sip/include/sip.h?view=diff&rev=385680&r1=385638&r2=385680
==============================================================================
--- team/group/pinefrog-rtcp-trunk/channels/sip/include/sip.h (original)
+++ team/group/pinefrog-rtcp-trunk/channels/sip/include/sip.h Sun Apr 14 19:58:50 2013
@@ -754,6 +754,8 @@
 	int compactheaders;         /*!< send compact sip headers */
 	int allow_external_domains; /*!< Accept calls to external SIP domains? */
 	int callevents;             /*!< Whether we send manager events or not */
+	int rtcpevents;             /*!< Whether we send manager RTCP events or not */
+	int rtcptimer;		    /*!< How often, during a call, to report RTCP stats */
 	int regextenonqualify;      /*!< Whether to add/remove regexten when qualifying peers */
 	int legacy_useroption_parsing; /*!< Whether to strip useroptions in URI via semicolons */
 	int send_diversion;	        /*!< Whether to Send SIP Diversion headers */
@@ -1163,6 +1165,7 @@
 	int waitid;                         /*!< Wait ID for scheduler after 491 or other delays */
 	int reinviteid;                     /*!< Reinvite in case of provisional, but no final response */
 	int autokillid;                     /*!< Auto-kill ID (scheduler) */
+	int rtcpeventid;                        /*!< Scheduler ID for RTCP Events */
 	int t38id;                          /*!< T.38 Response ID */
 	struct sip_refer *refer;            /*!< REFER: SIP transfer data structure */
 	enum subscriptiontype subscribed;   /*!< SUBSCRIBE: Is this dialog a subscription?  */
@@ -1192,6 +1195,9 @@
 	struct sip_srtp *srtp;              /*!< Structure to hold Secure RTP session data for audio */
 	struct sip_srtp *vsrtp;             /*!< Structure to hold Secure RTP session data for video */
 	struct sip_srtp *tsrtp;             /*!< Structure to hold Secure RTP session data for text */
+	struct ast_rtp_instance_stats *audioqual;       /*!< Audio: The latest quality report, for realtime storage */
+	struct ast_rtp_instance_stats *videoqual;       /*!< Video: The latest quality report, for realtime storage */
+	struct sip_settings *sip_cfg;                   /*! Which sip_cfg is associated with this dialog */
 
 	int red;                            /*!< T.140 RTP Redundancy */
 	int hangupcause;                    /*!< Storage of hangupcause copied from our owner before we disconnect from the AST channel (only used at hangup) */

Added: team/group/pinefrog-rtcp-trunk/channels/sip/rtcp.c
URL: http://svnview.digium.com/svn/asterisk/team/group/pinefrog-rtcp-trunk/channels/sip/rtcp.c?view=auto&rev=385680
==============================================================================
--- team/group/pinefrog-rtcp-trunk/channels/sip/rtcp.c (added)
+++ team/group/pinefrog-rtcp-trunk/channels/sip/rtcp.c Sun Apr 14 19:58:50 2013
@@ -1,0 +1,382 @@
+/*
+* Asterisk -- An open source telephony toolkit.
+*
+* Copyright (C) 2013 Olle E. Johansson, Edvina AB
+*
+* 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 rtcp.c
+*
+* \brief RTCP additional functions
+*
+* \author Olle E. Johansson <oej at edvina.net>
+*/
+
+/*** MODULEINFO
+	<support_level>core</support_level>
+***/
+
+#include "asterisk.h"
+
+ASTERISK_FILE_VERSION(__FILE__, "$Revision$")
+
+#include "asterisk/utils.h"
+#include "asterisk/manager.h"
+#include "asterisk/logger.h"
+#include "asterisk/translate.h"
+#include "asterisk/rtp_engine.h"
+#include "include/sip.h"
+#include "include/rtcp.h"
+
+/*! \brief Set various data items in the RTP structure, like channel identifier.
+ */
+void sip_rtcp_set_data(struct sip_pvt *dialog, struct ast_rtp_instance *instance, enum media_type type)
+{
+
+	if (dialog && dialog->owner) {
+		struct ast_channel *bridgepeer = ast_bridged_channel(dialog->owner);
+
+		if (bridgepeer) {
+			/* Store the bridged peer data while we have it */
+			ast_rtp_instance_set_bridged_chan(instance, ast_channel_name(dialog->owner), ast_channel_uniqueid(dialog->owner), S_OR(ast_channel_name(bridgepeer), ""), S_OR(ast_channel_uniqueid(bridgepeer), ""));
+			ast_debug(1, "---- Setting bridged peer name to %s\n", ast_channel_name(bridgepeer));
+		} else {
+			ast_rtp_instance_set_bridged_chan(instance, ast_channel_name(dialog->owner), ast_channel_uniqueid(dialog->owner), NULL, NULL);
+		}
+		ast_debug(1, "---- Setting channel name to %s\n", ast_channel_name(dialog->owner));
+
+ 		/* Try to find out if there's active transcoding */
+		/* Currently, the only media stream that has translation is the audio stream. At some point
+		   we might have transcoding for other types of media. */
+		if (type == SDP_AUDIO) {
+			const char *rtname = NULL, *wtname = NULL;
+			struct ast_trans_pvt *rt, *wt;
+
+			/* if we have a translator, the bridge delay is increased, which affects the QoS of the call.  */
+			rt = ast_channel_readtrans(dialog->owner);
+			wt = ast_channel_writetrans(dialog->owner);
+			if (rt) {
+				rtname = rt->t->name;
+			}
+			if (wt) {
+				wtname = wt->t->name;
+			}
+			if (rt || wt) {
+				ast_rtp_instance_set_translator(instance, rtname, rt ? rt->t->comp_cost : (const int) 0,
+					wtname, wt ? wt->t->comp_cost : (const int) 0);
+			}
+		
+			if (option_debug > 1) {
+ 				if (rt && rt->t) {
+ 					ast_debug(1, "--- Audio Read translator: %s Cost %d\n", rt->t->name, rt->t->comp_cost);
+ 				}
+ 				if (wt && wt->t) {
+ 					ast_debug(1, "--- Audio Write translator: %s Cost %d\n", wt->t->name, wt->t->comp_cost);
+ 				}
+			}
+		}
+
+	} else {
+ 		ast_debug(1, "######## Not setting rtcp media data. Dialog %s Dialog owner %s \n", dialog ? "set" : "unset",  dialog->owner ? "set" : "unset");
+	}
+}
+
+/*! \brief send manager report of RTCP 
+	reporttype = 0  means report during call (if configured)
+	reporttype = 1  means endof-call (hangup) report
+	reporttype = 10  means report at end of call leg (like transfer)
+*/
+void sip_rtcp_report(struct sip_pvt *dialog, struct ast_rtp_instance *instance, enum media_type media, int reporttype)
+{
+	struct ast_rtp_instance_stats qual;
+	//char *rtpqstring = NULL;
+	//int qosrealtime = ast_check_realtime("rtpcqr");
+	unsigned int duration;	/* Duration in secs */
+	memset(&qual, 0, sizeof(qual));
+	
+	sip_rtcp_set_data(dialog, instance, media);
+
+	if (ast_rtp_instance_get_stats(instance, &qual, AST_RTP_INSTANCE_STAT_ALL)) {
+ 		ast_debug(1, "######## Did not get any statistics... bad, bad, RTP instance\n");
+		/* Houston, we got a problem */
+		return;
+	}
+	
+	if (dialog->sip_cfg->rtcpevents) {
+		/* 
+		   If numberofreports == 0 we have no incoming RTCP active, thus we can't
+		   get any reliable data to handle packet loss or any RTT timing.
+		*/
+
+		duration = (unsigned int)(ast_tvdiff_ms(ast_tvnow(), qual.start) / 1000);
+		manager_event(EVENT_FLAG_CALL, "RTPQuality", 
+			"Channel: %s\r\n"			/* AST_CHANNEL for this call */
+			"Uniqueid: %s\r\n"			/* AST_CHANNEL for this call */
+			"BridgedChannel: %s\r\n"
+			"BridgedUniqueid: %s\r\n"
+			"RTPreporttype: %s\r\n"
+			"RTPrtcpstatus: %s\r\n"
+			"Duration: %u\r\n"		/* used in cdr_manager */
+			"PvtCallid: %s\r\n"		/* ??? Generic PVT identifier */
+			"RTPipaddress: %s\r\n"
+			"RTPmedia: %s\r\n"		/* Audio, video, text */
+			"RTPsendformat: %s\r\n"
+			"RTPrecvformat: %s\r\n"
+			"RTPlocalssrc: %u\r\n"
+			"RTPremotessrc: %u\r\n"
+			"RTPrtt: %f\r\n"
+			"RTPrttMax: %f\r\n"
+			"RTPrttMin: %f\r\n"
+			"RTPLocalJitter: %f\r\n"
+			"RTPRemoteJitter: %f\r\n" 
+			"RTPInPacketLoss: %d\r\n" 
+			"RTPInLocalPlPercent: %5.2f\r\n"
+			"RTPOutPacketLoss: %d\r\n"
+			"RTPOutPlPercent: %5.2f\r\n"
+			"TranslateRead: %s\r\n"
+			"TranslateReadCost: %d\r\n"
+			"TranslateWrite: %s\r\n"
+			"TranslateWriteCost: %d\r\n"
+			"\r\n", 
+			dialog->owner ? ast_channel_name(dialog->owner) : "",
+			dialog->owner ? ast_channel_uniqueid(dialog->owner) : "",
+			qual.bridgedchannel[0] ? qual.bridgedchannel : "" ,
+			qual.bridgeduniqueid[0] ? qual.bridgeduniqueid : "",
+			reporttype == 1 ? "Final" : "Update",
+			qual.numberofreports == 0 ? "Inactive" : "Active",
+			duration,
+			dialog->callid, 
+			ast_inet_ntoa(qual.them.sin_addr), 	
+			media == SDP_AUDIO ? "audio" : (media == SDP_VIDEO ? "video" : "fax") ,
+			ast_getformatname(&qual.lasttxformat),
+			ast_getformatname(&qual.lastrxformat),
+			qual.local_ssrc, 
+			qual.remote_ssrc,
+			qual.rtt,
+			qual.maxrtt,
+			qual.minrtt,
+			qual.rxjitter,
+			qual.txjitter,
+			qual.rxploss,
+			/* The local counter of lost packets in inbound stream divided with received packets plus lost packets */
+			(qual.remote_txcount + qual.rxploss) > 0 ? (double) qual.rxploss / (qual.remote_txcount + qual.rxploss) * 100 : 0,
+			qual.txploss,
+			/* The remote counter of lost packets (if we got the reports)
+			   divided with our counter of sent packets
+			 */
+			(qual.rxcount + qual.txploss) > 0 ? (double) qual.txploss / qual.rxcount  * 100 : 0,
+			qual.readtranslator, qual.readcost,
+			qual.writetranslator, qual.writecost
+		);
+	}
+
+	/* CDR records are not reliable when it comes to near-death-of-channel events, so we need to store the RTCP
+	   report in realtime when we have it.
+	   Tests have proven that storing to realtime from the call thread is NOT a good thing. Therefore, we just save
+	   the quality report structure in the PVT and let the function that kills the pvt store the stuff in the
+	   monitor thread instead.
+	 */
+	if (reporttype == 1) {
+		ast_log(LOG_DEBUG, "---- Activation qual structure in dialog \n");
+		qual.end = ast_tvnow();
+ 		qual.mediatype = media;
+		if (media == SDP_AUDIO) {  /* Audio */
+			dialog->audioqual = ast_calloc(1, sizeof(struct ast_rtp_instance_stats));
+			(* dialog->audioqual) = qual;
+		} else if (media == SDP_VIDEO) {  /* Video */
+			dialog->videoqual = ast_calloc(1,sizeof(struct ast_rtp_instance_stats));
+			(* dialog->videoqual) = qual;
+		}
+	}
+}
+
+/*! \brief Write quality report to realtime storage */
+void qos_write_realtime(struct sip_pvt *dialog, struct ast_rtp_instance_stats *qual)
+{
+	unsigned int duration;	/* Duration in secs */
+	char buf_duration[10], buf_lssrc[30], buf_rssrc[30];
+	char buf_rtt[10], buf_rttmin[10], buf_rttmax[10];
+	char localjitter[10], remotejitter[10];
+	char buf_readcost[5], buf_writecost[5];
+	char buf_mediatype[10];
+	char buf_remoteip[25];
+	char buf_inpacketloss[25], buf_outpacketloss[25];
+	char buf_outpackets[25], buf_inpackets[25];
+	int qosrealtime = ast_check_realtime("rtpcqr");
+
+
+	if (!qual) {
+		ast_log(LOG_ERROR, "No CQR data provided \n");
+		return;
+	}
+
+	/* Since the CDR is already gone, we need to calculate our own duration.
+	   The CDR duration is the definitive resource for billing, this is
+	   the RTP stream duration which may include early media (ringing and
+	   provider messages). Only useful for measurements.
+	 */
+	if (!ast_tvzero(qual->end) && !ast_tvzero(qual->start)) {
+		duration = (unsigned int)(ast_tvdiff_ms(qual->end, qual->start) / 1000);
+	} else {
+		ast_debug(2, "**** What? No duration? What type of call is THAT? \n");
+		duration = 0;
+	}
+
+	/* Realtime is based on strings, so let's make strings */
+	sprintf(localjitter, "%f", qual->rxjitter);
+	sprintf(remotejitter, "%f", qual->txjitter);
+	sprintf(buf_lssrc, "%u", qual->local_ssrc);
+	sprintf(buf_rssrc, "%u", qual->remote_ssrc);
+	sprintf(buf_rtt, "%.0f", qual->rtt);
+	sprintf(buf_rttmax, "%.0f", qual->maxrtt);
+	sprintf(buf_rttmin, "%.0f", qual->minrtt);
+	sprintf(buf_duration, "%u", duration);
+	sprintf(buf_readcost, "%d", qual->readcost);
+	sprintf(buf_writecost, "%d", qual->writecost);
+	sprintf(buf_mediatype,"%s", qual->mediatype == SDP_AUDIO ? "audio" : (qual->mediatype == SDP_VIDEO ? "video" : "fax") );
+	sprintf(buf_remoteip,"%s", ast_inet_ntoa(qual->them.sin_addr));
+	sprintf(buf_inpacketloss, "%d", qual->rxploss);
+	sprintf(buf_outpacketloss, "%d", qual->txploss);
+	sprintf(buf_inpackets, "%d", qual->rxcount);		/* Silly value. Need to check this */
+	sprintf(buf_outpackets, "%d", qual->txcount);
+	//sprintf(buf_inpackets, "%d", qual->remote_count);	/* Do check again */
+	//sprintf(buf_outpackets, "%d", qual->local_count);
+
+	ast_log(LOG_CQR, "CQR Channel: %s Uid %s Bch %s Buid %s Pvt %s Media %s Lssrc %s Rssrc %s Rip %s Rtt %s:%s:%s Ljitter %s Rjitter %s Rtcpstatus %s Dur %s Pout %s Plossout %s Pin %s Plossin %s\n",
+		qual->channel[0] ? qual->channel : "",
+		qual->uniqueid[0] ? qual->uniqueid : "",
+		qual->bridgedchannel[0] ? qual->bridgedchannel : "" ,
+		qual->bridgeduniqueid[0] ? qual->bridgeduniqueid : "",
+		dialog->callid,
+		buf_mediatype,
+		buf_lssrc,
+		buf_rssrc,
+		buf_remoteip,
+		buf_rtt, buf_rttmax, buf_rttmin,
+		localjitter,
+		remotejitter,
+		qual->numberofreports == 0 ? "Inactive" : "Active",
+		buf_duration,
+		buf_outpackets,
+		buf_outpacketloss,
+		buf_inpackets,
+		buf_inpacketloss);
+
+	if (!qosrealtime) {
+		return;
+	}
+/* Example database schema for MySQL:
+CREATE TABLE `astcqr` (
+  `channel` varchar(50) NOT NULL,
+  `uniqueid` varchar(35) NOT NULL,
+  `bridgedchannel` varchar(50) NOT NULL,
+  `bridgeduniqueid` varchar(35) NOT NULL,
+  `pvtcallid` varchar(80) NOT NULL,
+  `rtpmedia` varchar(50) NOT NULL,
+  `localssrc` varchar(50) NOT NULL,
+  `remotessrc` varchar(50) NOT NULL,
+  `rtt` varchar(10) NOT NULL,
+  `localjitter` varchar(10) NOT NULL,
+  `remotejitter` varchar(10) NOT NULL,
+  `sendformat` varchar(10) NOT NULL,
+  `receiveformat` varchar(10) NOT NULL,
+  `rtcpstatus` varchar(10) NOT NULL,
+  `duration` varchar(10) NOT NULL,
+  `packetsent` varchar(30) NOT NULL,
+  `packetreceived` varchar(30) NOT NULL,
+  `packetlossin` varchar(30) NOT NULL,
+  `packetlossout` varchar(30) NOT NULL,
+  `rttmax` varchar(12) NOT NULL,
+  `rttmin` varchar(12) NOT NULL,
+  `writetranslator` varchar(15) NOT NULL,
+  `readtranslator` varchar(15) NOT NULL,
+  `writecost` varchar(10) NOT NULL,
+  `readcost` varchar(10) NOT NULL,
+  `remoteip` varchar(25) NOT NULL,
+  KEY `ChannelUnique` (`channel`,`uniqueid`)
+) ENGINE=MyISAM DEFAULT CHARSET=latin1 COMMENT='FOr pinefrog stats'
+*/
+
+	ast_store_realtime("rtpcqr", 
+		"channel", qual->channel[0] ? qual->channel : "--no channel--",
+		"uniqueid", qual->uniqueid[0] ? qual->uniqueid : "--no uniqueid --",
+		"bridgedchannel", qual->bridgedchannel[0] ? qual->bridgedchannel : "" ,
+		"bridgeduniqueid", qual->bridgeduniqueid[0] ? qual->bridgeduniqueid : "",
+		"pvtcallid", dialog->callid, 
+		"rtpmedia", buf_mediatype, 
+		"localssrc", buf_lssrc, 
+		"remotessrc", buf_rssrc,
+		"remoteip", buf_remoteip,
+		"rtt", buf_rtt, 
+		"rttmax", buf_rttmax, 
+		"rttmin", buf_rttmin, 
+		"localjitter", localjitter, 
+		"remotejitter", remotejitter, 
+		"sendformat", ast_getformatname(&qual->lasttxformat),
+		"receiveformat", ast_getformatname(&qual->lastrxformat),
+		"rtcpstatus", qual->numberofreports == 0 ? "Inactive" : "Active",
+		"duration", buf_duration,
+		"writetranslator", qual->writetranslator[0] ? qual->writetranslator : "",
+		"writecost", buf_writecost,
+		"readtranslator", qual->readtranslator[0] ? qual->readtranslator : "",
+		"readcost", buf_readcost,
+		"packetlossin", buf_inpacketloss,
+		"packetlossout", buf_outpacketloss,
+		"packetsent", buf_outpackets,
+		"packetreceived", buf_inpackets,
+		NULL);
+}
+
+/*! \brief Send RTCP manager events */
+int send_rtcp_events(const void *data)
+{
+	struct sip_pvt *dialog = (struct sip_pvt *) data;
+	ast_log(LOG_DEBUG, "***** SENDING RTCP EVENT \n");
+
+	if (dialog->rtp && !ast_rtp_instance_isactive(dialog->rtp)) {
+		ast_debug(1, "          ***** Activating RTCP report \n");
+		sip_rtcp_report(dialog, dialog->rtp, SDP_AUDIO, FALSE);
+	} else {
+		ast_debug(1, "          ***** NOT Activating RTCP report \n");
+	}
+	if (dialog->vrtp && !ast_rtp_instance_isactive(dialog->vrtp)) {
+		sip_rtcp_report(dialog, dialog->vrtp, SDP_VIDEO, FALSE);
+	}
+	return (dialog->sip_cfg ? dialog->sip_cfg->rtcptimer : 0);
+}
+
+/*! \brief Activate RTCP events at start of call */
+void start_rtcp_events(struct sip_pvt *dialog, struct ast_sched_context *sched)
+{
+	ast_debug(2, "***** STARTING SENDING RTCP EVENT \n");
+	/* Check if it's already active */
+
+	if (dialog->rtp && !ast_rtp_instance_isactive(dialog->rtp)) {
+		sip_rtcp_set_data(dialog, dialog->rtp, SDP_AUDIO);
+	}
+	if (dialog->vrtp && !ast_rtp_instance_isactive(dialog->vrtp)) {
+		sip_rtcp_set_data(dialog, dialog->vrtp, SDP_VIDEO);
+	}
+
+	if (!dialog->sip_cfg->rtcpevents || !dialog->sip_cfg->rtcptimer) {
+		ast_debug(2, "***** NOT SENDING RTCP EVENTS \n");
+		return;
+	}
+
+	if (dialog->rtcpeventid != -1) {
+		return;
+	}
+
+
+	/*! \brief Schedule events */
+	dialog->rtcpeventid = ast_sched_add(sched, dialog->sip_cfg->rtcptimer * 1000, send_rtcp_events, dialog);
+}

Propchange: team/group/pinefrog-rtcp-trunk/channels/sip/rtcp.c
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: team/group/pinefrog-rtcp-trunk/channels/sip/rtcp.c
------------------------------------------------------------------------------
    svn:keywords = Author Date Id Revision

Propchange: team/group/pinefrog-rtcp-trunk/channels/sip/rtcp.c
------------------------------------------------------------------------------
    svn:mime-type = text/plain

Modified: team/group/pinefrog-rtcp-trunk/contrib/realtime/mysql/sippeers.sql
URL: http://svnview.digium.com/svn/asterisk/team/group/pinefrog-rtcp-trunk/contrib/realtime/mysql/sippeers.sql?view=diff&rev=385680&r1=385638&r2=385680
==============================================================================
--- team/group/pinefrog-rtcp-trunk/contrib/realtime/mysql/sippeers.sql (original)
+++ team/group/pinefrog-rtcp-trunk/contrib/realtime/mysql/sippeers.sql Sun Apr 14 19:58:50 2013
@@ -5,19 +5,19 @@
 CREATE TABLE IF NOT EXISTS `sippeers` (
       `id` int(11) NOT NULL AUTO_INCREMENT,
       `name` varchar(10) NOT NULL,
-      `ipaddr` varchar(45) DEFAULT NULL,
+      `ipaddr` varchar(15) DEFAULT NULL,
       `port` int(5) DEFAULT NULL,
       `regseconds` int(11) DEFAULT NULL,
       `defaultuser` varchar(10) DEFAULT NULL,
-      `fullcontact` varchar(80) DEFAULT NULL,
+      `fullcontact` varchar(35) DEFAULT NULL,
       `regserver` varchar(20) DEFAULT NULL,
       `useragent` varchar(20) DEFAULT NULL,
       `lastms` int(11) DEFAULT NULL,
       `host` varchar(40) DEFAULT NULL,
       `type` enum('friend','user','peer') DEFAULT NULL,
       `context` varchar(40) DEFAULT NULL,
-      `permit` varchar(95) DEFAULT NULL,
-      `deny` varchar(95) DEFAULT NULL,
+      `permit` varchar(40) DEFAULT NULL,
+      `deny` varchar(40) DEFAULT NULL,
       `secret` varchar(40) DEFAULT NULL,
       `md5secret` varchar(40) DEFAULT NULL,
       `remotesecret` varchar(40) DEFAULT NULL,
@@ -56,7 +56,7 @@
       `fromdomain` varchar(40) DEFAULT NULL,
       `fromuser` varchar(40) DEFAULT NULL,
       `qualify` varchar(40) DEFAULT NULL,
-      `defaultip` varchar(45) DEFAULT NULL,
+      `defaultip` varchar(40) DEFAULT NULL,
       `rtptimeout` int(11) DEFAULT NULL,
       `rtpholdtimeout` int(11) DEFAULT NULL,
       `sendrpid` enum('yes','no') DEFAULT NULL,
@@ -66,8 +66,8 @@
       `timerb` int(11) DEFAULT NULL,
       `qualifyfreq` int(11) DEFAULT NULL,
       `constantssrc` enum('yes','no') DEFAULT NULL,
-      `contactpermit` varchar(95) DEFAULT NULL,
-      `contactdeny` varchar(95) DEFAULT NULL,
+      `contactpermit` varchar(40) DEFAULT NULL,
+      `contactdeny` varchar(40) DEFAULT NULL,
       `usereqphone` enum('yes','no') DEFAULT NULL,
       `textsupport` enum('yes','no') DEFAULT NULL,
       `faxdetect` enum('yes','no') DEFAULT NULL,

Modified: team/group/pinefrog-rtcp-trunk/contrib/realtime/postgresql/realtime.sql
URL: http://svnview.digium.com/svn/asterisk/team/group/pinefrog-rtcp-trunk/contrib/realtime/postgresql/realtime.sql?view=diff&rev=385680&r1=385638&r2=385680
==============================================================================
--- team/group/pinefrog-rtcp-trunk/contrib/realtime/postgresql/realtime.sql (original)
+++ team/group/pinefrog-rtcp-trunk/contrib/realtime/postgresql/realtime.sql Sun Apr 14 19:58:50 2013
@@ -40,7 +40,7 @@
 canreinvite character varying(3) DEFAULT 'yes',
 supportpath character varying(3) DEFAULT 'no',
 context character varying(80),
-defaultip character varying(45),
+defaultip character varying(15),
 dtmfmode character varying(7),
 fromuser character varying(80),
 fromdomain character varying(80),

Modified: team/group/pinefrog-rtcp-trunk/include/asterisk/logger.h
URL: http://svnview.digium.com/svn/asterisk/team/group/pinefrog-rtcp-trunk/include/asterisk/logger.h?view=diff&rev=385680&r1=385638&r2=385680
==============================================================================
--- team/group/pinefrog-rtcp-trunk/include/asterisk/logger.h (original)
+++ team/group/pinefrog-rtcp-trunk/include/asterisk/logger.h Sun Apr 14 19:58:50 2013
@@ -209,7 +209,18 @@
 #endif
 #define AST_LOG_DTMF    __LOG_DTMF, _A_
 
-#define NUMLOGLEVELS 32
+#ifdef LOG_CQR
+#undef LOG_CQR
+#endif
+#define __LOG_CQR  7
+#define LOG_CQR    __LOG_CQR, _A_
+
+#ifdef AST_LOG_CQR
+#undef AST_LOG_CQR
+#endif
+#define AST_LOG_CQR    __LOG_CQR, _A_
+
+#define NUMLOGLEVELS 64		/* Highest bit */
 
 /*!
  * \brief Get the debug level for a module

Modified: team/group/pinefrog-rtcp-trunk/include/asterisk/rtp_engine.h
URL: http://svnview.digium.com/svn/asterisk/team/group/pinefrog-rtcp-trunk/include/asterisk/rtp_engine.h?view=diff&rev=385680&r1=385638&r2=385680
==============================================================================
--- team/group/pinefrog-rtcp-trunk/include/asterisk/rtp_engine.h (original)
+++ team/group/pinefrog-rtcp-trunk/include/asterisk/rtp_engine.h Sun Apr 14 19:58:50 2013
@@ -74,6 +74,7 @@
 #include "asterisk/netsock2.h"
 #include "asterisk/sched.h"
 #include "asterisk/res_srtp.h"
+#include "asterisk/channel.h"
 
 /* Maximum number of payloads supported */
 #if defined(LOW_MEMORY)
@@ -215,6 +216,14 @@
 	AST_RTP_INSTANCE_STAT_LOCAL_SSRC,
 	/*! Retrieve remote SSRC */
 	AST_RTP_INSTANCE_STAT_REMOTE_SSRC,
+	/*! Retrieve local CNAME */
+	AST_RTP_INSTANCE_STAT_LOCAL_CNAME,
+	/*! Retrieve remote SDES */
+	AST_RTP_INSTANCE_STAT_REMOTE_CNAME,
+	/*! Retrieve start time */
+	AST_RTP_INSTANCE_STAT_START,
+	/*! Retrieve IP Address */
+	AST_RTP_INSTANCE_STAT_IP,
 };
 
 /* Codes for RTP-specific data - not defined by our AST_FORMAT codes */
@@ -246,10 +255,12 @@
 	unsigned int txcount;
 	/*! Number of packets received */
 	unsigned int rxcount;
+
 	/*! Jitter on transmitted packets */
 	double txjitter;
 	/*! Jitter on received packets */
 	double rxjitter;
+
 	/*! Maximum jitter on remote side */
 	double remote_maxjitter;
 	/*! Minimum jitter on remote side */
@@ -300,6 +311,32 @@
 	unsigned int local_ssrc;
 	/*! Their SSRC */
 	unsigned int remote_ssrc;
+
+	/* --- Pinefrog additions */
+	/*! Remote: Number of packets transmitted */
+	unsigned int remote_txcount;
+	/*! Remote: Number of packets received */
+	unsigned int remote_rxcount;
+	char channel[AST_MAX_EXTENSION];	/*!< Name of channel */
+	char uniqueid[AST_MAX_EXTENSION];	/*!< uniqueid of channel */
+	char bridgedchannel[AST_MAX_EXTENSION];	/*!< Name of bridged channel */
+	char bridgeduniqueid[AST_MAX_EXTENSION];	/*!< uniqueid of bridged channel */
+	unsigned int numberofreports;	  /*!< Number of reports received from remote end */
+	struct ast_format lasttxformat;		  /*!< Last used codec on transmitted stream */
+	struct ast_format lastrxformat;		  /*!< Last used codec on received stream */
+	struct sockaddr_in them;	  /*!< The IP address used for media by remote end */
+	struct sockaddr_in us;	  	  /*!< The IP address used for media by our end */
+	char ourcname[255];		/*!< Our SDES RTP session name (CNAME) */
+	size_t ourcnamelength;		/*!< Length of CNAME (utf8) */
+	char theircname[255];		/*!< Their SDES RTP session name (CNAME) */
+	size_t theircnamelength;	/*!< Length of CNAME (utf8) */
+	struct timeval start;		  /*!< When the stream started */
+	struct timeval end;		  /*!< When the stream ended */
+	char writetranslator[80];	  /*!< Translator used when writing */
+	char readtranslator[80];		  /*!< Translator providing frames when reading */
+	int writecost;		  /*!< Cost in milliseconds for encoding/decoding 1 second of outbound media */
+	int readcost;		  /*!< Cost in milliseconds for encoding/decoding 1 second of inbound media */
+	int mediatype;			/*! Type of media */
 };
 
 #define AST_RTP_STAT_SET(current_stat, combined, placement, value) \
@@ -420,6 +457,9 @@
 	int (*destroy)(struct ast_rtp_instance *instance);
 	/*! Callback for writing out a frame */
 	int (*write)(struct ast_rtp_instance *instance, struct ast_frame *frame);
+	/*! Callback for stopping the outbound RTP media for an instance,
+	    but keeping the RTCP flow (and the RTP keepalives if needed) */
+	void (*hold)(struct ast_rtp_instance *instance, int status);
 	/*! Callback for stopping the RTP instance */
 	void (*stop)(struct ast_rtp_instance *instance);
 	/*! Callback for starting RFC2833 DTMF transmission */
@@ -481,6 +521,15 @@
 	struct ast_rtp_engine_ice *ice;
 	/*! Callback to pointer for optional DTLS SRTP support */
 	struct ast_rtp_engine_dtls *dtls;
+	/*! Callback to check if a media stram is active */
+	int (*isactive)(struct ast_rtp_instance *instance);
+	/*! Callback to set CNAME in rtcp  */
+	void (*setcname)(struct ast_rtp_instance *instance, const char *cname, size_t length);
+	/*! Callback to set information about bridged channel for CQR record */
+	void (*set_bridged_chan)(struct ast_rtp_instance *instance, const char *channel, const char *uniqueid, const char *bridgedchan, const char *bridgeduniqueid);

[... 1341 lines stripped ...]



More information about the asterisk-commits mailing list