[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