[svn-commits] mjordan: trunk r393740 - in /trunk: channels/ include/asterisk/ main/ res/

SVN commits to the Digium repositories svn-commits at lists.digium.com
Fri Jul 5 12:33:41 CDT 2013


Author: mjordan
Date: Fri Jul  5 12:33:33 2013
New Revision: 393740

URL: http://svnview.digium.com/svn/asterisk?view=rev&rev=393740
Log:
Refactor RTCP events over to Stasis; associate with channels

This patch does the following:

* It merges Jaco Kroon's patch from ASTERISK-20754, which provides channel
  information in the RTCP events. Because Stasis provides a cache, Jaco's
  patch was modified to pass the channel uniqueid to the RTP layer as
  opposed to a pointer to the channel. This has the following benefits:
  (1) It keeps the RTP engine 'clean' of references back to channels
  (2) It prevents circular dependencies and other potential ref counting issues
* The RTP engine now allows any RTP implementation to raise RTCP messages.
  Potentially, other implementations (such as res_rtp_multicast) could also
  raise RTCP information. The engine provides structs to represent RTCP headers
  and RTCP SR/RR reports.
* Some general refactoring in res_rtp_asterisk was done to try and tame the
  RTCP code. It isn't perfect - that's *way* beyond the scope of this work -
  but it does feel marginally better.
* A few random bugs were fixed in the RTCP statistics. (Example: performing an
  assignment of a = a is probably not correct)
* We now raise RTCP events for each SR/RR sent/received. Previously we wouldn't
  raise an event when we sent a RR report.

Note that this work will be of use to others who want to monitor call quality
or build modules that report call quality statistics. Since the events are now
moving across the Stasis message bus, this is far easier to accomplish. It is
also a first step (though by no means the last step) towards getting Olle's
pinefrog work incorporated.

Again: note that the patch by Jaco Kroon was modified slightly for this work;
however, he did all of the hard work in finding the right places to set the
channel in the RTP engine across the channel drivers. Much thanks goes to Jaco
for his hard work here.

Review: https://reviewboard.asterisk.org/r/2603/

(closes issue ASTERISK-20574)
Reported by: Jaco Kroon
patches:
  asterisk-rtcp-channel.patch uploaded by jkroon (License 5671)

(closes issue ASTERISK-21471)
Reported by: Matt Jordan


Modified:
    trunk/channels/chan_gtalk.c
    trunk/channels/chan_gulp.c
    trunk/channels/chan_h323.c
    trunk/channels/chan_jingle.c
    trunk/channels/chan_mgcp.c
    trunk/channels/chan_motif.c
    trunk/channels/chan_multicast_rtp.c
    trunk/channels/chan_sip.c
    trunk/channels/chan_skinny.c
    trunk/channels/chan_unistim.c
    trunk/include/asterisk/cdr.h
    trunk/include/asterisk/channel.h
    trunk/include/asterisk/json.h
    trunk/include/asterisk/rtp_engine.h
    trunk/main/asterisk.c
    trunk/main/json.c
    trunk/main/manager.c
    trunk/main/rtp_engine.c
    trunk/res/res_rtp_asterisk.c

Modified: trunk/channels/chan_gtalk.c
URL: http://svnview.digium.com/svn/asterisk/trunk/channels/chan_gtalk.c?view=diff&rev=393740&r1=393739&r2=393740
==============================================================================
--- trunk/channels/chan_gtalk.c (original)
+++ trunk/channels/chan_gtalk.c Fri Jul  5 12:33:33 2013
@@ -210,6 +210,7 @@
 static int gtalk_update_externip(void);
 static int gtalk_parser(void *data, ikspak *pak);
 static int gtalk_create_candidates(struct gtalk *client, struct gtalk_pvt *p, char *sid, char *from, char *to);
+static void gtalk_set_owner(struct gtalk_pvt *p, struct ast_channel *chan);
 
 /*! \brief PBX interface structure for channel registration */
 static struct ast_channel_tech gtalk_tech = {
@@ -1007,6 +1008,17 @@
 	return 1;
 }
 
+static void gtalk_set_owner(struct gtalk_pvt *p, struct ast_channel *chan)
+{
+	p->owner = chan;
+	if (p->rtp) {
+		ast_rtp_instance_set_channel_id(p->rtp, chan ? ast_channel_uniqueid(chan) : "");
+	}
+	if (p->vrtp) {
+		ast_rtp_instance_set_channel_id(p->vrtp, chan ? ast_channel_uniqueid(chan) : "");
+	}
+}
+
 static struct gtalk_pvt *gtalk_alloc(struct gtalk *client, const char *us, const char *them, const char *sid)
 {
 	struct gtalk_pvt *tmp = NULL;
@@ -1198,7 +1210,7 @@
 		ast_channel_musicclass_set(tmp, client->musicclass);
 	if (!ast_strlen_zero(client->parkinglot))
 		ast_channel_parkinglot_set(tmp, client->parkinglot);
-	i->owner = tmp;
+	gtalk_set_owner(i, tmp);
 	ast_module_ref(ast_module_info->self);
 	ast_channel_context_set(tmp, client->context);
 	ast_channel_exten_set(tmp, i->exten);
@@ -1712,8 +1724,9 @@
 		ast_mutex_unlock(&p->lock);
 		return -1;
 	}
-	if (p->owner == oldchan)
-		p->owner = newchan;
+	if (p->owner == oldchan) {
+		gtalk_set_owner(p, newchan);
+	}
 	ast_mutex_unlock(&p->lock);
 	return 0;
 }
@@ -1889,7 +1902,7 @@
 
 	ast_mutex_lock(&p->lock);
 	client = p->parent;
-	p->owner = NULL;
+	gtalk_set_owner(p, NULL);
 	ast_channel_tech_pvt_set(ast, NULL);
 	if (!p->alreadygone) {
 		gtalk_action(client, p, "terminate");

Modified: trunk/channels/chan_gulp.c
URL: http://svnview.digium.com/svn/asterisk/trunk/channels/chan_gulp.c?view=diff&rev=393740&r1=393739&r2=393740
==============================================================================
--- trunk/channels/chan_gulp.c (original)
+++ trunk/channels/chan_gulp.c Fri Jul  5 12:33:33 2013
@@ -429,7 +429,7 @@
 {
 	RAII_VAR(struct ast_datastore *, datastore, NULL, ao2_cleanup);
 
-	if (session->endpoint->direct_media_glare_mitigation == 
+	if (session->endpoint->direct_media_glare_mitigation ==
 			AST_SIP_DIRECT_MEDIA_GLARE_MITIGATION_NONE) {
 		return 0;
 	}
@@ -563,6 +563,13 @@
 	pvt->media[SIP_MEDIA_AUDIO] = ao2_find(session->media, "audio", OBJ_KEY);
 	pvt->media[SIP_MEDIA_VIDEO] = ao2_find(session->media, "video", OBJ_KEY);
 	ast_channel_tech_pvt_set(chan, pvt);
+	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));
+	}
+
 
 	if (ast_format_cap_is_empty(session->req_caps) || !ast_format_cap_has_joint(session->req_caps, session->endpoint->codecs)) {
 		ast_format_cap_copy(ast_channel_nativeformats(chan), session->endpoint->codecs);
@@ -742,8 +749,15 @@
 static int fixup(void *data)
 {
 	struct fixup_data *fix_data = data;
+	struct gulp_pvt *pvt = ast_channel_tech_pvt(fix_data->chan);
 
 	fix_data->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));
+	}
 
 	return 0;
 }
@@ -1434,6 +1448,19 @@
 	return h_data;
 }
 
+/*! \brief Clear a channel from a session along with its PVT */
+static void clear_session_and_channel(struct ast_sip_session *session, struct ast_channel *ast, struct gulp_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, "");
+	}
+	ast_channel_tech_pvt_set(ast, NULL);
+}
+
 static int hangup(void *data)
 {
 	pj_status_t status;
@@ -1453,9 +1480,7 @@
 		}
 	}
 
-	session->channel = NULL;
-	ast_channel_tech_pvt_set(ast, NULL);
-
+	clear_session_and_channel(session, ast, pvt);
 	ao2_cleanup(pvt);
 	ao2_cleanup(h_data);
 
@@ -1485,11 +1510,9 @@
 	/* Go ahead and do our cleanup of the session and channel even if we're not going
 	 * to be able to send our SIP request/response
 	 */
+	clear_session_and_channel(session, ast, pvt);
+	ao2_cleanup(pvt);
 	ao2_cleanup(h_data);
-	session->channel = NULL;
-	ast_channel_tech_pvt_set(ast, NULL);
-
-	ao2_cleanup(pvt);
 
 	return -1;
 }
@@ -1859,8 +1882,8 @@
  * Module loading including tests for configuration or dependencies.
  * This function can return AST_MODULE_LOAD_FAILURE, AST_MODULE_LOAD_DECLINE,
  * or AST_MODULE_LOAD_SUCCESS. If a dependency or environment variable fails
- * tests return AST_MODULE_LOAD_FAILURE. If the module can not load the 
- * configuration file or other non-critical problem return 
+ * tests return AST_MODULE_LOAD_FAILURE. If the module can not load the
+ * configuration file or other non-critical problem return
  * AST_MODULE_LOAD_DECLINE. On success return AST_MODULE_LOAD_SUCCESS.
  */
 static int load_module(void)

Modified: trunk/channels/chan_h323.c
URL: http://svnview.digium.com/svn/asterisk/trunk/channels/chan_h323.c?view=diff&rev=393740&r1=393739&r2=393740
==============================================================================
--- trunk/channels/chan_h323.c (original)
+++ trunk/channels/chan_h323.c Fri Jul  5 12:33:33 2013
@@ -250,6 +250,8 @@
 static void delete_aliases(void);
 static void prune_peers(void);
 
+static void oh323_set_owner(struct oh323_pvt *pvt, struct ast_channel *c);
+
 static struct ast_channel *oh323_request(const char *type, struct ast_format_cap *cap, const struct ast_channel *requestor, const char *dest, int *cause);
 static int oh323_digit_begin(struct ast_channel *c, char digit);
 static int oh323_digit_end(struct ast_channel *c, char digit, unsigned int duration);
@@ -719,7 +721,7 @@
 		return 0;
 	}
 
-	pvt->owner = NULL;
+	oh323_set_owner(pvt, NULL);
 	ast_channel_tech_pvt_set(c, NULL);
 
 	if (ast_channel_hangupcause(c)) {
@@ -974,7 +976,7 @@
 		ast_log(LOG_WARNING, "old channel wasn't %p but was %p\n", oldchan, pvt->owner);
 		return -1;
 	}
-	pvt->owner = newchan;
+	oh323_set_owner(p, newchan);
 	ast_mutex_unlock(&pvt->lock);
 	return 0;
 }
@@ -1007,6 +1009,7 @@
 		ast_debug(1, "Created RTP channel\n");
 
 	ast_rtp_instance_set_qos(pvt->rtp, tos, cos, "H323 RTP");
+	ast_rtp_instance_set_channel_id(pvt->rtp, pvt->owner ? ast_channel_uniqueid(pvt->owner), "");
 
 	if (h323debug)
 		ast_debug(1, "Setting NAT on RTP to %d\n", pvt->options.nat);
@@ -1100,7 +1103,7 @@
 		/* Register channel functions. */
 		ast_channel_tech_pvt_set(ch, pvt);
 		/* Set the owner of this channel */
-		pvt->owner = ch;
+		oh323_set_owner(pvt, ch);
 
 		ast_channel_context_set(ch, pvt->context);
 		ast_channel_exten_set(ch, pvt->exten);
@@ -1187,6 +1190,14 @@
 	iflist = pvt;
 	ast_mutex_unlock(&iflock);
 	return pvt;
+}
+
+static void oh323_set_owner(struct oh323_pvt *pvt, struct ast_channel *chan)
+{
+	pvt->owner = chan;
+	if (pvt->rtp) {
+		ast_rtp_instance_set_channel_id(pvt, chan ? ast_channel_uniqueid(chan) : "");
+	}
 }
 
 static struct oh323_pvt *find_call_locked(int call_reference, const char *token)

Modified: trunk/channels/chan_jingle.c
URL: http://svnview.digium.com/svn/asterisk/trunk/channels/chan_jingle.c?view=diff&rev=393740&r1=393739&r2=393740
==============================================================================
--- trunk/channels/chan_jingle.c (original)
+++ trunk/channels/chan_jingle.c Fri Jul  5 12:33:33 2013
@@ -196,6 +196,7 @@
 static struct jingle_pvt *jingle_alloc(struct jingle *client, const char *from, const char *sid);
 static char *jingle_show_channels(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a);
 static char *jingle_do_reload(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a);
+static void jingle_set_owner(struct jingle_pvt *pvt, struct ast_channel *chan);
 
 /*! \brief PBX interface structure for channel registration */
 static struct ast_channel_tech jingle_tech = {
@@ -833,6 +834,17 @@
 	return tmp;
 }
 
+static void jingle_set_owner(struct jingle_pvt *pvt, struct ast_channel *chan)
+{
+	pvt->owner = chan;
+	if (pvt->rtp) {
+		ast_rtp_instance_set_channel_id(pvt->rtp, pvt->owner ? ast_channel_uniqueid(pvt->owner) : "");
+	}
+	if (pvt->vrtp) {
+		ast_rtp_instance_set_channel_id(pvt->vrtp, pvt->owner ? ast_channel_uniqueid(pvt->owner) : "");
+	}
+}
+
 /*! \brief Start new jingle channel */
 static struct ast_channel *jingle_new(struct jingle *client, struct jingle_pvt *i, int state, const char *title, const char *linkedid)
 {
@@ -908,7 +920,7 @@
 		ast_channel_language_set(tmp, client->language);
 	if (!ast_strlen_zero(client->musicclass))
 		ast_channel_musicclass_set(tmp, client->musicclass);
-	i->owner = tmp;
+	jingle_set_owner(i, tmp);
 	ast_channel_context_set(tmp, client->context);
 	ast_channel_exten_set(tmp, i->exten);
 	/* Don't use ast_set_callerid() here because it will
@@ -1321,8 +1333,9 @@
 		ast_mutex_unlock(&p->lock);
 		return -1;
 	}
-	if (p->owner == oldchan)
-		p->owner = newchan;
+	if (p->owner == oldchan) {
+		jingle_set_owner(p, newchan);
+	}
 	ast_mutex_unlock(&p->lock);
 	return 0;
 }
@@ -1540,7 +1553,7 @@
 
 	ast_mutex_lock(&p->lock);
 	client = p->parent;
-	p->owner = NULL;
+	jingle_set_owner(p, NULL);
 	ast_channel_tech_pvt_set(ast, NULL);
 	if (!p->alreadygone)
 		jingle_action(client, p, JINGLE_TERMINATE);

Modified: trunk/channels/chan_mgcp.c
URL: http://svnview.digium.com/svn/asterisk/trunk/channels/chan_mgcp.c?view=diff&rev=393740&r1=393739&r2=393740
==============================================================================
--- trunk/channels/chan_mgcp.c (original)
+++ trunk/channels/chan_mgcp.c Fri Jul  5 12:33:33 2013
@@ -431,6 +431,7 @@
 
 static struct sockaddr_in bindaddr;
 
+static void mgcp_set_owner(struct mgcp_subchannel *sub, struct ast_channel *chan);
 static struct ast_frame  *mgcp_read(struct ast_channel *ast);
 static int transmit_response(struct mgcp_subchannel *sub, char *msg, struct mgcp_request *req, char *msgrest);
 static int transmit_notify_request(struct mgcp_subchannel *sub, char *tone);
@@ -528,7 +529,7 @@
 	}
 	ast_debug(1, "Released sub %d of channel %s@%s\n", sub->id, p->name, p->parent->name);
 
-	sub->owner = NULL;
+	mgcp_set_owner(sub, NULL);
 	if (!ast_strlen_zero(sub->cxident)) {
 		transmit_connection_del(sub);
 	}
@@ -945,7 +946,7 @@
 		}
 	}
 
-	sub->owner = NULL;
+	mgcp_set_owner(sub, NULL);
 
 	/* for deleting gate */
 	if (p->pktcgatealloc && sub->gate) {
@@ -1225,6 +1226,13 @@
 	return f;
 }
 
+static void mgcp_set_owner(struct mgcp_subchannel *sub, struct ast_channel *chan)
+{
+	sub->owner = chan;
+	if (sub->rtp) {
+		ast_rtp_instance_set_channel_id(sub->rtp, sub->owner ? ast_channel_uniqueid(chan) : "");
+	}
+}
 
 static struct ast_frame *mgcp_read(struct ast_channel *ast)
 {
@@ -1288,7 +1296,7 @@
 		ast_log(LOG_WARNING, "old channel wasn't %p but was %p\n", oldchan, sub->owner);
 		return -1;
 	}
-	sub->owner = newchan;
+	mgcp_set_owner(sub, newchan);
 	ast_mutex_unlock(&sub->lock);
 	return 0;
 }
@@ -1529,7 +1537,7 @@
 			ast_channel_accountcode_set(tmp, i->accountcode);
 		if (i->amaflags)
 			ast_channel_amaflags_set(tmp, i->amaflags);
-		sub->owner = tmp;
+		mgcp_set_owner(sub, tmp);
 		ast_module_ref(ast_module_info->self);
 		ast_channel_callgroup_set(tmp, i->callgroup);
 		ast_channel_pickupgroup_set(tmp, i->pickupgroup);

Modified: trunk/channels/chan_motif.c
URL: http://svnview.digium.com/svn/asterisk/trunk/channels/chan_motif.c?view=diff&rev=393740&r1=393739&r2=393740
==============================================================================
--- trunk/channels/chan_motif.c (original)
+++ trunk/channels/chan_motif.c Fri Jul  5 12:33:33 2013
@@ -656,6 +656,18 @@
 	.update_peer = jingle_set_rtp_peer,
 };
 
+/*! \brief Set the channel owner on the \ref jingle_session object and related objects */
+static void jingle_set_owner(struct jingle_session *session, struct ast_channel *chan)
+{
+	session->owner = chan;
+	if (session->rtp) {
+		ast_rtp_instance_set_channel_id(session->rtp, session->owner ? ast_channel_uniqueid(session->owner) : "");
+	}
+	if (session->vrtp) {
+		ast_rtp_instance_set_channel_id(session->vrtp, session->owner ? ast_channel_uniqueid(session->owner) : "");
+	}
+}
+
 /*! \brief Internal helper function which enables video support on a sesson if possible */
 static void jingle_enable_video(struct jingle_session *session)
 {
@@ -679,7 +691,7 @@
 	}
 
 	ast_rtp_instance_set_prop(session->vrtp, AST_RTP_PROPERTY_RTCP, 1);
-
+	ast_rtp_instance_set_channel_id(session->vrtp, ast_channel_uniqueid(session->owner));
 	ast_channel_set_fd(session->owner, 2, ast_rtp_instance_fd(session->vrtp, 0));
 	ast_channel_set_fd(session->owner, 3, ast_rtp_instance_fd(session->vrtp, 1));
 	ast_rtp_codecs_packetization_set(ast_rtp_instance_get_codecs(session->vrtp), session->vrtp, &session->prefs);
@@ -775,7 +787,7 @@
 
 	ast_channel_tech_set(chan, &jingle_tech);
 	ast_channel_tech_pvt_set(chan, session);
-	session->owner = chan;
+	jingle_set_owner(session, chan);
 
 	ast_channel_callid_set(chan, session->callid);
 
@@ -1712,7 +1724,7 @@
 
 	ao2_lock(session);
 
-	session->owner = newchan;
+	jingle_set_owner(session, newchan);
 
 	ao2_unlock(session);
 
@@ -1862,7 +1874,7 @@
 	}
 
 	ast_channel_tech_pvt_set(ast, NULL);
-	session->owner = NULL;
+	jingle_set_owner(session, NULL);
 
 	ao2_unlink(session->state->sessions, session);
 	ao2_ref(session->state, -1);

Modified: trunk/channels/chan_multicast_rtp.c
URL: http://svnview.digium.com/svn/asterisk/trunk/channels/chan_multicast_rtp.c?view=diff&rev=393740&r1=393739&r2=393740
==============================================================================
--- trunk/channels/chan_multicast_rtp.c (original)
+++ trunk/channels/chan_multicast_rtp.c Fri Jul  5 12:33:33 2013
@@ -153,7 +153,7 @@
 		ast_rtp_instance_destroy(instance);
 		goto failure;
 	}
-
+	ast_rtp_instance_set_channel_id(instance, ast_channel_uniqueid(chan));
 	ast_rtp_instance_set_remote_address(instance, &destination_address);
 
 	ast_channel_tech_set(chan, &multicast_rtp_tech);

Modified: trunk/channels/chan_sip.c
URL: http://svnview.digium.com/svn/asterisk/trunk/channels/chan_sip.c?view=diff&rev=393740&r1=393739&r2=393740
==============================================================================
--- trunk/channels/chan_sip.c (original)
+++ trunk/channels/chan_sip.c Fri Jul  5 12:33:33 2013
@@ -1240,6 +1240,7 @@
 static int get_sip_pvt_from_replaces(const char *callid, const char *totag, const char *fromtag,
 		struct sip_pvt **out_pvt, struct ast_channel **out_chan);
 static void check_pendings(struct sip_pvt *p);
+static void sip_set_owner(struct sip_pvt *p, struct ast_channel *chan);
 
 static void *sip_pickup_thread(void *stuff);
 static int sip_pickup(struct ast_channel *chan);
@@ -3494,7 +3495,7 @@
 		ast_channel_tech_pvt_set(owner, dialog_unref(ast_channel_tech_pvt(owner), "resetting channel dialog ptr in unlink_all"));
 		ast_channel_unlock(owner);
 		ast_channel_unref(owner);
-		dialog->owner = NULL;
+		sip_set_owner(dialog, NULL);
 	}
 	sip_pvt_unlock(dialog);
 
@@ -7183,7 +7184,7 @@
 		ast_clear_flag(&p->flags[0], SIP_DEFER_BYE_ON_TRANSFER);	/* Really hang up next time */
 		ast_channel_tech_pvt_set(p->owner, dialog_unref(ast_channel_tech_pvt(p->owner), "unref p->owner->tech_pvt"));
 		sip_pvt_lock(p);
-		p->owner = NULL;  /* Owner will be gone after we return, so take it away */
+		sip_set_owner(p, NULL); /* Owner will be gone after we return, so take it away */
 		sip_pvt_unlock(p);
 		ast_module_unref(ast_module_info->self);
 		return 0;
@@ -7218,7 +7219,7 @@
 	/* Disconnect */
 	disable_dsp_detect(p);
 
-	p->owner = NULL;
+	sip_set_owner(p, NULL);
 	ast_channel_tech_pvt_set(ast, dialog_unref(ast_channel_tech_pvt(ast), "unref ast->tech_pvt"));
 
 	ast_module_unref(ast_module_info->self);
@@ -7544,7 +7545,7 @@
 	if (p->owner != oldchan)
 		ast_log(LOG_WARNING, "old channel wasn't %p but was %p\n", oldchan, p->owner);
 	else {
-		p->owner = newchan;
+		sip_set_owner(p, newchan);
 		/* Re-invite RTP back to Asterisk. Needed if channel is masqueraded out of a native
 		   RTP bridge (i.e., RTP not going through Asterisk): RTP bridge code might not be
 		   able to do this if the masquerade happens before the bridge breaks (e.g., AMI
@@ -8190,7 +8191,7 @@
 		}
 		ast_channel_zone_set(tmp, zone);
 	}
-	i->owner = tmp;
+	sip_set_owner(i, tmp);
 	ast_module_ref(ast_module_info->self);
 	ast_channel_context_set(tmp, i->context);
 	/*Since it is valid to have extensions in the dialplan that have unescaped characters in them
@@ -9250,6 +9251,21 @@
 
 	/* If owner exists, it is locked and reffed */
 	return pvt->owner;
+}
+
+/*! \brief Set the owning channel on the \ref sip_pvt object */
+static void sip_set_owner(struct sip_pvt *p, struct ast_channel *chan)
+{
+	p->owner = chan;
+	if (p->rtp) {
+		ast_rtp_instance_set_channel_id(p->rtp, p->owner ? ast_channel_uniqueid(p->owner) : "");
+	}
+	if (p->vrtp) {
+		ast_rtp_instance_set_channel_id(p->vrtp, p->owner ? ast_channel_uniqueid(p->owner) : "");
+	}
+	if (p->trtp) {
+		ast_rtp_instance_set_channel_id(p->trtp, p->owner ? ast_channel_uniqueid(p->owner) : "");
+	}
 }
 
 /*! \brief find or create a dialog structure for an incoming SIP message.

Modified: trunk/channels/chan_skinny.c
URL: http://svnview.digium.com/svn/asterisk/trunk/channels/chan_skinny.c?view=diff&rev=393740&r1=393739&r2=393740
==============================================================================
--- trunk/channels/chan_skinny.c (original)
+++ trunk/channels/chan_skinny.c Fri Jul  5 12:33:33 2013
@@ -1638,6 +1638,7 @@
 static int skinny_dialer_cb(const void *data);
 static int skinny_reload(void);
 
+static void skinny_set_owner(struct skinny_subchannel* sub, struct ast_channel* chan);
 static void setsubstate(struct skinny_subchannel *sub, int state);
 static void dumpsub(struct skinny_subchannel *sub, int forcehangup);
 static void activatesub(struct skinny_subchannel *sub, int state);
@@ -4797,10 +4798,12 @@
 	}
 
 	if (sub->rtp && sub->owner) {
+		ast_rtp_instance_set_channel_id(sub->rtp, ast_channel_uniqueid(sub->owner));
 		ast_channel_set_fd(sub->owner, 0, ast_rtp_instance_fd(sub->rtp, 0));
 		ast_channel_set_fd(sub->owner, 1, ast_rtp_instance_fd(sub->rtp, 1));
 	}
 	if (hasvideo && sub->vrtp && sub->owner) {
+		ast_rtp_instance_set_channel_id(sub->vrtp, ast_channel_uniqueid(sub->owner));
 		ast_channel_set_fd(sub->owner, 2, ast_rtp_instance_fd(sub->vrtp, 0));
 		ast_channel_set_fd(sub->owner, 3, ast_rtp_instance_fd(sub->vrtp, 1));
 	}
@@ -5009,7 +5012,7 @@
 	SKINNY_DEBUG(DEBUG_SUB, 3, "Sub %d - Destroying\n", sub->callid);
 
 	ast_mutex_lock(&sub->lock);
-	sub->owner = NULL;
+	skinny_set_owner(sub, NULL);
 	ast_channel_tech_pvt_set(ast, NULL);
 	destroy_rtp(sub);
 	ast_free(sub->origtonum);
@@ -5133,7 +5136,7 @@
 		ast_log(LOG_WARNING, "old channel wasn't %p but was %p\n", oldchan, sub->owner);
 		return -1;
 	}
-	sub->owner = newchan;
+	skinny_set_owner(sub, newchan);
 	return 0;
 }
 
@@ -5361,6 +5364,17 @@
 	return 0;
 }
 
+static void skinny_set_owner(struct skinny_subchannel* sub, struct ast_channel* chan)
+{
+	sub->owner = chan;
+	if (sub->rtp) {
+		ast_rtp_instance_set_channel_id(sub->rtp, sub->owner ? ast_channel_uniqueid(sub->owner) : "");
+	}
+	if (sub->vrtp) {
+		ast_rtp_instance_set_channel_id(sub->vrtp, sub->owner ? ast_channel_uniqueid(sub->owner) : "");
+	}
+}
+
 static struct ast_channel *skinny_new(struct skinny_line *l, struct skinny_subline *subline, int state, const char *linkedid, int direction)
 {
 	struct ast_channel *tmp;
@@ -5386,7 +5400,7 @@
 		} else {
 			ast_mutex_init(&sub->lock);
 
-			sub->owner = tmp;
+			skinny_set_owner(sub, tmp);
 			sub->callid = callnums++;
 			d->lastlineinstance = l->instance;
 			d->lastcallreference = sub->callid;

Modified: trunk/channels/chan_unistim.c
URL: http://svnview.digium.com/svn/asterisk/trunk/channels/chan_unistim.c?view=diff&rev=393740&r1=393739&r2=393740
==============================================================================
--- trunk/channels/chan_unistim.c (original)
+++ trunk/channels/chan_unistim.c Fri Jul  5 12:33:33 2013
@@ -675,6 +675,7 @@
 static int reload(void);
 static int unload_module(void);
 static int reload_config(void);
+static void unistim_set_owner(struct unistim_subchannel *sub, struct ast_channel *chan);
 static void show_main_page(struct unistimsession *pte);
 static struct ast_channel *unistim_request(const char *type, struct ast_format_cap *cap, const struct ast_channel *requestor,
 	const char *dest, int *cause);
@@ -2749,6 +2750,7 @@
 		return;
 	}
 	ast_rtp_instance_set_prop(sub->rtp, AST_RTP_PROPERTY_RTCP, 1);
+	ast_rtp_instance_set_channel_id(sub->rtp, ast_channel_uniqueid(sub->owner));
 	ast_channel_internal_fd_set(sub->owner, 0, ast_rtp_instance_fd(sub->rtp, 0));
 	ast_channel_internal_fd_set(sub->owner, 1, ast_rtp_instance_fd(sub->rtp, 1));
 	ast_rtp_instance_set_qos(sub->rtp, qos.tos_audio, qos.cos_audio, "UNISTIM RTP");
@@ -4736,7 +4738,7 @@
 static int unistim_hangup_clean(struct ast_channel *ast, struct unistim_subchannel *sub) {
 	ast_mutex_lock(&sub->lock);
 	ast_channel_tech_pvt_set(ast, NULL);
-	sub->owner = NULL;
+	unistim_set_owner(sub, NULL);
 	sub->alreadygone = 0;
 	ast_mutex_unlock(&sub->lock);
 	if (sub->rtp) {
@@ -5072,7 +5074,7 @@
 		return -1;
 	}
 
-	p->owner = newchan;
+	unistim_set_owner(p, newchan);
 
 	ast_mutex_unlock(&p->lock);
 
@@ -5589,7 +5591,7 @@
 	if (!ast_strlen_zero(l->parent->language)) {
 		ast_channel_language_set(tmp, l->parent->language);
 	}
-	sub->owner = tmp;
+	unistim_set_owner(sub, tmp);
 	ast_update_use_count();
 	ast_channel_callgroup_set(tmp, l->callgroup);
 	ast_channel_pickupgroup_set(tmp, l->pickupgroup);
@@ -5621,6 +5623,14 @@
 	}
 
 	return tmp;
+}
+
+static void unistim_set_owner(struct unistim_subchannel *sub, struct ast_channel *chan)
+{
+	sub->owner = chan;
+	if (sub->rtp) {
+		ast_rtp_instance_set_channel_id(sub->rtp, sub->owner ? ast_channel_uniqueid(sub->owner) : "");
+	}
 }
 
 static void *do_monitor(void *data)

Modified: trunk/include/asterisk/cdr.h
URL: http://svnview.digium.com/svn/asterisk/trunk/include/asterisk/cdr.h?view=diff&rev=393740&r1=393739&r2=393740
==============================================================================
--- trunk/include/asterisk/cdr.h (original)
+++ trunk/include/asterisk/cdr.h Fri Jul  5 12:33:33 2013
@@ -330,11 +330,10 @@
 	char peeraccount[AST_MAX_ACCOUNT_CODE];
 	/*! flags */
 	unsigned int flags;
-	/*! Unique Channel Identifier
-	 * 150 = 127 (max systemname) + "-" + 10 (epoch timestamp) + "." + 10 (monotonically incrementing integer) + NULL */
-	char uniqueid[150];
+	/*! Unique Channel Identifier */
+	char uniqueid[AST_MAX_UNIQUEID];
 	/* Linked group Identifier */
-	char linkedid[32];
+	char linkedid[AST_MAX_UNIQUEID];
 	/*! User field */
 	char userfield[AST_MAX_USER_FIELD];
 	/*! Sequence field */

Modified: trunk/include/asterisk/channel.h
URL: http://svnview.digium.com/svn/asterisk/trunk/include/asterisk/channel.h?view=diff&rev=393740&r1=393739&r2=393740
==============================================================================
--- trunk/include/asterisk/channel.h (original)
+++ trunk/include/asterisk/channel.h Fri Jul  5 12:33:33 2013
@@ -133,6 +133,12 @@
 
 #define AST_MAX_EXTENSION       80  /*!< Max length of an extension */
 #define AST_MAX_CONTEXT         80  /*!< Max length of a context */
+#define AST_MAX_UNIQUEID       150  /*!< Max length of a channel uniqueid */
+/*                                   150 = 127 (max systemname) + "-" + 10 (epoch
+ *                                   timestamp) + "." + 10 (monotonically incrementing
+ *                                   integer) + NULL. Note that if this value is ever
+ *                                   changed, MAX_CHANNEL_ID should be updated in
+ *                                   rtp_engine.h */
 #define AST_MAX_ACCOUNT_CODE    20  /*!< Max length of an account code */
 #define AST_CHANNEL_NAME        80  /*!< Max length of an ast_channel name */
 #define MAX_LANGUAGE            40  /*!< Max length of the language setting */

Modified: trunk/include/asterisk/json.h
URL: http://svnview.digium.com/svn/asterisk/trunk/include/asterisk/json.h?view=diff&rev=393740&r1=393739&r2=393740
==============================================================================
--- trunk/include/asterisk/json.h (original)
+++ trunk/include/asterisk/json.h Fri Jul  5 12:33:33 2013
@@ -329,6 +329,34 @@
  * \return -1 on error.
  */
 int ast_json_integer_set(struct ast_json *integer, intmax_t value);
+
+/*!
+ * \brief Create a JSON real number.
+ * \since 12.0.0
+ * \param value Value of the new JSON real number.
+ * \return Newly allocated real number.
+ * \return \c NULL on error.
+ */
+struct ast_json *ast_json_real_create(double value);
+
+/*!
+ * \brief Get the value from a JSON real number.
+ * \since 12.0.0
+ * \param real JSON real number.
+ * \return Value of a JSON real number.
+ * \return 0 if \a real is not a JSON real number.
+ */
+double ast_json_real_get(const struct ast_json *real);
+
+/*!
+ * \brief Set the value of a JSON real number.
+ * \since 12.0.0
+ * \param integer JSON real number to modify.
+ * \param value New value for \a real.
+ * \return 0 on success.
+ * \return -1 on error.
+ */
+int ast_json_real_set(struct ast_json *real, double value);
 
 /*!@}*/
 

Modified: trunk/include/asterisk/rtp_engine.h
URL: http://svnview.digium.com/svn/asterisk/trunk/include/asterisk/rtp_engine.h?view=diff&rev=393740&r1=393739&r2=393740
==============================================================================
--- trunk/include/asterisk/rtp_engine.h (original)
+++ trunk/include/asterisk/rtp_engine.h Fri Jul  5 12:33:33 2013
@@ -74,6 +74,7 @@
 #include "asterisk/netsock2.h"
 #include "asterisk/sched.h"
 #include "asterisk/res_srtp.h"
+#include "asterisk/stasis.h"
 
 /* Maximum number of payloads supported */
 #if defined(LOW_MEMORY)
@@ -84,6 +85,12 @@
 
 /* Maximum number of generations */
 #define AST_RED_MAX_GENERATION 5
+
+/* Maximum size of an Asterisk channel unique ID. Should match AST_MAX_UNIQUEID.
+ * Note that we don't use that defined value directly here to avoid a hard dependency
+ * on channel.h
+ */
+#define MAX_CHANNEL_ID 150
 
 struct ast_rtp_instance;
 struct ast_rtp_glue;
@@ -215,6 +222,8 @@
 	AST_RTP_INSTANCE_STAT_LOCAL_SSRC,
 	/*! Retrieve remote SSRC */
 	AST_RTP_INSTANCE_STAT_REMOTE_SSRC,
+	/*! Retrieve channel unique ID */
+	AST_RTP_INSTANCE_STAT_CHANNEL_UNIQUEID,
 };
 
 /* Codes for RTP-specific data - not defined by our AST_FORMAT codes */
@@ -238,6 +247,46 @@
 	int rtp_code;
 	/*! Actual payload number */
 	int payload;
+};
+
+/* Common RTCP report types */
+/*! Sender Report */
+#define AST_RTP_RTCP_SR 200
+/*! Receiver Report */
+#define AST_RTP_RTCP_RR 201
+
+/*!
+ * \since 12
+ * \brief A report block within a SR/RR report */
+struct ast_rtp_rtcp_report_block {
+	unsigned int source_ssrc;         /*< The SSRC of the source for this report block */
+	struct {
+		unsigned short fraction;      /*< The fraction of packets lost since last SR/RR */
+		unsigned int packets;         /*< The cumulative packets since the beginning */
+	} lost_count;                     /*< Statistics regarding missed packets */
+	unsigned int highest_seq_no;      /*< Extended highest sequence number received */
+	unsigned int ia_jitter;           /*< Calculated interarrival jitter */
+	unsigned int lsr;                 /*< The time the last SR report was received */
+	unsigned int dlsr;                /*< Delay in sending this report */
+};
+
+/*!
+ * \since 12
+ * \brief An object that represents data sent during a SR/RR RTCP report */
+struct ast_rtp_rtcp_report {
+	unsigned short reception_report_count;     /*< The number of report blocks */
+	unsigned int ssrc;                         /*< Our SSRC */
+	unsigned int type;                         /*< The type of report. 200=SR; 201=RR */
+	struct {
+		struct timeval ntp_timestamp;          /*< Our NTP timestamp */
+		unsigned int rtp_timestamp;            /*< Our last RTP timestamp */
+		unsigned int packet_count;             /*< Number of packets sent */
+		unsigned int octet_count;              /*< Number of bytes sent */
+	} sender_information;                      /*< Sender information for SR */
+	/*! A dynamic array of report blocks. The number of elements is given by
+	 * \c reception_report_count.
+	 */
+	struct ast_rtp_rtcp_report_block *report_block[0];
 };
 
 /*! Structure that represents statistics from an RTP instance */
@@ -300,6 +349,8 @@
 	unsigned int local_ssrc;
 	/*! Their SSRC */
 	unsigned int remote_ssrc;
+	/*! The Asterisk channel's unique ID that owns this instance */
+	char channel_uniqueid[MAX_CHANNEL_ID];
 };
 
 #define AST_RTP_STAT_SET(current_stat, combined, placement, value) \
@@ -308,6 +359,14 @@
 if (stat == current_stat) { \
 return 0; \
 } \
+}
+
+#define AST_RTP_STAT_STRCPY(current_stat, combined, placement, value) \
+if (stat == current_stat || stat == AST_RTP_INSTANCE_STAT_ALL || (combined >= 0 && combined == current_stat)) { \
+	ast_copy_string(placement, value, sizeof(placement)); \
+	if (stat == current_stat) { \
+		return 0; \
+	} \
 }
 
 #define AST_RTP_STAT_TERMINATOR(combined) \
@@ -1541,6 +1600,30 @@
 struct ast_rtp_glue *ast_rtp_instance_get_glue(const char *type);
 
 /*!
+ * \brief Get the unique ID of the channel that owns this RTP instance
+ *
+ * Note that this should remain valid for the lifetime of the RTP instance.
+ *
+ * \param instance The RTP instance
+ *
+ * \retval The unique ID of the channel
+ * \retval Empty string if no channel owns this RTP instance
+ *
+ * \since 12
+ */
+const char *ast_rtp_instance_get_channel_id(struct ast_rtp_instance *instance);
+
+/*!
+ * \brief Set the channel that owns this RTP instance
+ *
+ * \param instance The RTP instance
+ * \param uniqueid The uniqueid of the channel
+ *
+ * \since 12
+ */
+void ast_rtp_instance_set_channel_id(struct ast_rtp_instance *instance, const char *uniqueid);
+
+/*!
  * \brief Get the other RTP instance that an instance is bridged to
  *
  * \param instance The RTP instance that we want
@@ -1965,27 +2048,6 @@
 struct ast_rtp_glue *ast_rtp_instance_get_active_glue(struct ast_rtp_instance *instance);
 
 /*!
- * \brief Get the channel that is associated with an RTP instance while in a bridge
- *
- * \param instance The RTP instance
- *
- * \retval pointer to the channel
- *
- * Example:
- *
- * \code
- * struct ast_channel *chan = ast_rtp_instance_get_chan(instance);
- * \endcode
- *
- * This gets the channel associated with the RTP instance pointed to by 'instance'.
- *
- * \note This will only return a channel while in a local or remote bridge.
- *
- * \since 1.8
- */
-struct ast_channel *ast_rtp_instance_get_chan(struct ast_rtp_instance *instance);
-
-/*!
  * \brief Send a comfort noise packet to the RTP instance
  *
  * \param instance The RTP instance
@@ -2073,6 +2135,62 @@
  */
 void ast_rtp_dtls_cfg_free(struct ast_rtp_dtls_cfg *dtls_cfg);
 
+struct ast_json;
+
+/*!
+ * \brief Allocate an ao2 ref counted instance of \ref ast_rtp_rtcp_report
+ *
+ * \param report_blocks The number of report blocks to allocate
+ * \retval An ao2 ref counted \ref ast_rtp_rtcp_report object on success
+ * \retval NULL on error
+ */
+struct ast_rtp_rtcp_report *ast_rtp_rtcp_report_alloc(unsigned int report_blocks);
+
+/*!
+ * \since 12
+ * \brief Publish an RTCP message to \ref stasis
+ *
+ * \param rtp The rtp instance object
+ * \param message_type The RTP message type to publish
+ * \param report The RTCP report object to publish. This should be an ao2 ref counted
+ *  object. This routine will increase the reference count of the object.
+ * \param blob Additional JSON objects to publish along with the RTCP information
+ */
+void ast_rtp_publish_rtcp_message(struct ast_rtp_instance *rtp,
+		struct stasis_message_type *message_type,
+		struct ast_rtp_rtcp_report *report,
+		struct ast_json *blob);
+
+/*! \addtogroup StasisTopicsAndMessages
+ * @{
+ */
+
+/*!
+ * \since 12
+ * \brief Message type for an RTCP message sent from this Asterisk instance
+ *
+ * \retval A stasis message type
+ */
+struct stasis_message_type *ast_rtp_rtcp_sent_type(void);
+
+/*!
+ * \since 12
+ * \brief Message type for an RTCP message received from some external source
+ *
+ * \retval A stasis message type
+ */
+struct stasis_message_type *ast_rtp_rtcp_received_type(void);
+
+/*!
+ * \since 12
+ * \brief \ref stasis topic for RTP and RTCP related messages
+ *
+ * \retval A \ref stasis topic
+ */
+struct stasis_topic *ast_rtp_topic(void);
+
+/* }@ */
+
 #if defined(__cplusplus) || defined(c_plusplus)
 }
 #endif

Modified: trunk/main/asterisk.c
URL: http://svnview.digium.com/svn/asterisk/trunk/main/asterisk.c?view=diff&rev=393740&r1=393739&r2=393740
==============================================================================
--- trunk/main/asterisk.c (original)
+++ trunk/main/asterisk.c Fri Jul  5 12:33:33 2013
@@ -27,7 +27,7 @@
  * internals of the Asterisk software. This documentation contains basic
  * examples, developer documentation, support information, and information
  * for upgrading.
- * 
+ *
  * \section community Community
  * Asterisk is a big project and has a busy community. Look at the
  * resources for questions and stick around to help answer questions.
@@ -120,7 +120,7 @@
  * \par
  * Use http://www.freenode.net IRC server to connect with Asterisk
  * developers and users in realtime.
- * 
+ *
  * \li \verbatim #asterisk \endverbatim Asterisk Users Room
  * \li \verbatim #asterisk-dev \endverbatim Asterisk Developers Room
  *
@@ -4217,6 +4217,7 @@
 		printf("Stasis initialization failed.\n%s", term_quit());
 		exit(1);
 	}
+
 	if (stasis_system_topic_init()) {
 		printf("Stasis system-level information initialization failed.\n%s", term_quit());
 		exit(1);
@@ -4258,7 +4259,10 @@
 
 	ast_format_attr_init();
 	ast_format_list_init();
-	ast_rtp_engine_init();
+	if (ast_rtp_engine_init()) {
+		printf("%s", term_quit());
+		exit(1);
+	}
 
 	ast_autoservice_init();
 

Modified: trunk/main/json.c
URL: http://svnview.digium.com/svn/asterisk/trunk/main/json.c?view=diff&rev=393740&r1=393739&r2=393740
==============================================================================
--- trunk/main/json.c (original)
+++ trunk/main/json.c Fri Jul  5 12:33:33 2013
@@ -214,6 +214,20 @@
 	return json_integer_set((json_t *)integer, value);
 }
 
+struct ast_json *ast_json_real_create(double value)
+{
+	return (struct ast_json *)json_real(value);
+}
+
+double ast_json_real_get(const struct ast_json *real)
+{
+	return json_real_value((json_t *)real);
+}
+
+int ast_json_real_set(struct ast_json *real, double value)
+{
+	return json_real_set((json_t *)real, value);
+}
 
 int ast_json_equal(const struct ast_json *lhs, const struct ast_json *rhs)
 {

Modified: trunk/main/manager.c
URL: http://svnview.digium.com/svn/asterisk/trunk/main/manager.c?view=diff&rev=393740&r1=393739&r2=393740
==============================================================================
--- trunk/main/manager.c (original)
+++ trunk/main/manager.c Fri Jul  5 12:33:33 2013
@@ -98,6 +98,7 @@
 #include "asterisk/json.h"
 #include "asterisk/bridging.h"
 #include "asterisk/features_config.h"
+#include "asterisk/rtp_engine.h"
 
 /*** DOCUMENTATION
 	<manager name="Ping" language="en_US">
@@ -1070,6 +1071,9 @@
 
 /*! \brief The \ref stasis_message_router for all \ref stasis messages */
 static struct stasis_message_router *stasis_router;
+
+/*! \brief The \ref stasis_subscription for forwarding the RTP topic to the AMI topic */
+static struct stasis_subscription *rtp_topic_forwarder;
 
 #define MGR_SHOW_TERMINAL_WIDTH 80
 
@@ -7775,6 +7779,11 @@
 	if (!manager_topic) {
 		return -1;
 	}
+	rtp_topic_forwarder = stasis_forward_all(ast_rtp_topic(), manager_topic);
+	if (!rtp_topic_forwarder) {
+		return -1;
+	}
+
 	stasis_router = stasis_message_router_create(manager_topic);
 	if (!stasis_router) {
 		return -1;

Modified: trunk/main/rtp_engine.c
URL: http://svnview.digium.com/svn/asterisk/trunk/main/rtp_engine.c?view=diff&rev=393740&r1=393739&r2=393740
==============================================================================

[... 1316 lines stripped ...]



More information about the svn-commits mailing list