[asterisk-commits] tzafrir: branch tzafrir/monitor-rtp r214078 - /team/tzafrir/monitor-rtp/res/

SVN commits to the Asterisk project asterisk-commits at lists.digium.com
Tue Aug 25 15:03:58 CDT 2009


Author: tzafrir
Date: Tue Aug 25 15:03:55 2009
New Revision: 214078

URL: http://svn.asterisk.org/svn-view/asterisk?view=rev&rev=214078
Log:
bulk of the rtp monitoring code

At the moment we don't have a simple way to allocate RTP port numbers,
hence the recorded channels are responsible for providing the variable
RTP_PORT_OFFSET . The actual UDP port number used will be:

  base + 2(${RTP_PORT_OFFSET} - 1)

where 'base' defaults to 9000 for the RX side and 11000 for the TX side.

Modified:
    team/tzafrir/monitor-rtp/res/res_monitor.c

Modified: team/tzafrir/monitor-rtp/res/res_monitor.c
URL: http://svn.asterisk.org/svn-view/asterisk/team/tzafrir/monitor-rtp/res/res_monitor.c?view=diff&rev=214078&r1=214077&r2=214078
==============================================================================
--- team/tzafrir/monitor-rtp/res/res_monitor.c (original)
+++ team/tzafrir/monitor-rtp/res/res_monitor.c Tue Aug 25 15:03:55 2009
@@ -478,6 +478,127 @@
 	return 0;
 }
 
+static int monitor2rtp_stop(struct ast_channel *chan, int need_lock)
+{
+	ast_log(LOG_NOTICE, "STOP monitor2rtp\n");
+	LOCK_IF_NEEDED(chan, need_lock);
+	if ((chan->monitor)) {
+		struct monitor_rtp_state *rtp_state_rx;
+		struct monitor_rtp_state *rtp_state_tx;
+
+		rtp_state_rx = (struct monitor_rtp_state *)
+			ast_filestream_xxx_get_filename(chan->monitor->read_stream);
+		rtp_state_tx = (struct monitor_rtp_state *)
+			ast_filestream_xxx_get_filename(chan->monitor->write_stream);
+
+		if (chan->monitor->read_stream) {
+			ast_log(LOG_NOTICE, "%s: close read_stream\n", __FUNCTION__);
+			if(rtp_state_rx) {
+				send_cdr(chan, 0, 1, rtp_state_rx);
+				/* FIXME: make sure no memory leak on the 'close' below:
+				chan->monitor->read_stream->filename = NULL;
+				ast_free(rtp_state_rx);
+				*/
+			}
+			ast_closestream(chan->monitor->read_stream);
+		}
+		if (chan->monitor->write_stream) {
+			ast_log(LOG_NOTICE, "%s: close write_stream\n", __FUNCTION__);
+			if(rtp_state_tx) {
+				send_cdr(chan, 0, 0, rtp_state_tx);
+				/* FIXME: make sure no memory leak on the 'close' below:
+				chan->monitor->write_stream->filename = NULL;
+				ast_free(rtp_state_tx);
+				*/
+			}
+			ast_closestream(chan->monitor->write_stream);
+		}
+	}
+	UNLOCK_IF_NEEDED(chan, need_lock);
+	return 0;
+}
+
+static void calc_ssrc(struct ast_channel *chan, uint32_t *rx_ssrc, uint32_t *tx_ssrc)
+{
+	float	val;
+
+	if(chan->uniqueid && sscanf(chan->uniqueid, "%f", &val) == 1) {
+		time_t		t;
+		int		a;
+		uint32_t	ssrc;
+
+		t = (time_t)val;
+		a = (val - t) * 10;
+		ast_log(LOG_DEBUG, "%s: val=%f t=%lu a=%d\n", __FUNCTION__, val, (unsigned long)t, a);
+		ssrc = (t << 8) | ((a << 4) & 0xFF);
+		ast_log(LOG_DEBUG, "%s: ssrc=%u\n", __FUNCTION__, ssrc);
+		*rx_ssrc = ssrc;
+		*tx_ssrc = ssrc | 0x1;
+		return;
+	}
+	ast_log(LOG_WARNING,
+		"%s: Failed to parse uniqueid='%s' using random SSRC\n",
+		__FUNCTION__, chan->uniqueid);
+	*rx_ssrc = ast_random();
+	*tx_ssrc = ast_random();
+}
+
+static int monitor2rtp_start(struct ast_channel *chan, int need_lock)
+{
+	struct ast_channel_monitor *monitor;
+	struct monitor_rtp_state *rtp_state_rx;
+	struct monitor_rtp_state *rtp_state_tx;
+	const char	*port_offset;
+	uint32_t	rx_ssrc;
+	uint32_t	tx_ssrc;
+	int		portnum;
+	int		ret = -1;
+
+	ast_log(LOG_NOTICE, "START monitor2rtp\n");
+	LOCK_IF_NEEDED(chan, need_lock);
+	port_offset = pbx_builtin_getvar_helper(chan, "RTP_PORT_OFFSET");
+	portnum = atoi(port_offset);
+	if(portnum <= 0) {
+		ast_log(LOG_WARNING, "Bad RTP_PORT_OFFSET='%s'\n", port_offset);
+		goto out;
+	}
+	if (!(monitor = ast_calloc(1, sizeof(*monitor)))) {
+		goto out;
+	}
+	calc_ssrc(chan, &rx_ssrc, &tx_ssrc);
+	ast_log(LOG_NOTICE, "%s: rx_ssrc=%u tx_ssrc=%u\n", __FUNCTION__, rx_ssrc, tx_ssrc);
+	/* RTP uses even port numbers */
+	portnum = (portnum - 1) * 2;
+	/* RX port */
+	monitor->read_stream = rtp_stream(chan, rtp_server_name, rtp_portbase_rx + portnum, rx_ssrc);
+	if (!monitor->read_stream) {
+		ast_log(LOG_WARNING, "Could not create UDP stream for read\n");
+		goto out;
+	}
+	/* TX port */
+	monitor->write_stream = rtp_stream(chan, rtp_server_name, rtp_portbase_tx + portnum, tx_ssrc);
+	if (!monitor->write_stream) {
+		ast_log(LOG_WARNING, "Could not create UDP stream for write\n");
+		ast_closestream(monitor->read_stream);
+		goto out;
+	}
+	rtp_state_rx = (struct monitor_rtp_state *)
+		ast_filestream_xxx_get_filename(chan->monitor->read_stream);
+	rtp_state_tx = (struct monitor_rtp_state *)
+		ast_filestream_xxx_get_filename(chan->monitor->write_stream);
+	send_cdr(chan, 1, 1, rtp_state_rx);
+	send_cdr(chan, 1, 0, rtp_state_tx);
+	monitor->stop = monitor2rtp_stop;
+	chan->monitor = monitor;
+	ast_monitor_set_state(chan, AST_MONITOR_RUNNING);
+	/* so we know this call has been monitored in case we need to bill for it or something */
+	pbx_builtin_setvar_helper(chan, "__MONITORED","true");
+	ret = 0;
+out:
+	UNLOCK_IF_NEEDED(chan, need_lock);
+	return 0;
+}
+
 /*! \brief Start monitoring a channel
  * \param chan ast_channel struct to record
  * \param format_spec file format to use for recording




More information about the asterisk-commits mailing list