[asterisk-commits] oej: branch oej/pinefrog-1.4 r237655 - in /team/oej/pinefrog-1.4: ./ main/ res/
SVN commits to the Asterisk project
asterisk-commits at lists.digium.com
Tue Jan 5 05:21:37 CST 2010
Author: oej
Date: Tue Jan 5 05:21:33 2010
New Revision: 237655
URL: http://svnview.digium.com/svn/asterisk?view=rev&rev=237655
Log:
Preparing for RTCP labs this afternoon...
Added:
team/oej/pinefrog-1.4/README.pinefrog-rtcp (with props)
Modified:
team/oej/pinefrog-1.4/ (props changed)
team/oej/pinefrog-1.4/main/channel.c
team/oej/pinefrog-1.4/main/rtp.c
team/oej/pinefrog-1.4/res/res_features.c
Propchange: team/oej/pinefrog-1.4/
------------------------------------------------------------------------------
--- automerge (original)
+++ automerge Tue Jan 5 05:21:33 2010
@@ -1,1 +1,1 @@
-Note to myself: Try to understand chan_sip
+http://www.codename-pineapple.org/
Added: team/oej/pinefrog-1.4/README.pinefrog-rtcp
URL: http://svnview.digium.com/svn/asterisk/team/oej/pinefrog-1.4/README.pinefrog-rtcp?view=auto&rev=237655
==============================================================================
--- team/oej/pinefrog-1.4/README.pinefrog-rtcp (added)
+++ team/oej/pinefrog-1.4/README.pinefrog-rtcp Tue Jan 5 05:21:33 2010
@@ -1,0 +1,65 @@
+Olle E. Johansson
+oej at edvina.net
+
+
+
+
+
+
+
+
+Pinefrog - RTCP cleanup and additions
+-------------------------------------
+
+RTCP, as defined in RFC 3550, is a protocol that co-exists with RTP, the protocol used
+for realtime multimedia in VoIP. RTCP gives the endpoints a tool to exchange data about
+the media streams exchanged. As a result, both ends can get informaiton about the
+latency for data sent in both directions, packet loss and jitter for each media stream.
+
+A VoIP call is at least two media streams and they can have different properties in
+regards of quality. A router or switch in the middle could have a lot of outbound traffic,
+causing delays and possible packet loss. This might not affect inbound traffic.
+
+In Asterisk, the RTCP handler is part of the RTP module. The RTP module produces RTCP
+report that can be added to channel variables, cdr logs or sent through AMI.
+
+In 1.4, the data used is mostly based on the latest report, it's not aggregated. This
+is fixed in trunk.
+
+In both implementations (and the 1.6 releases in between) the RTCP support is not
+very complete.
+
+- It doesn't handle RTCP SDES packets
+- It doesn't send RTCP END packets at end of session
+- It doesn't handle receiving END packets
+- It doesn't handle re-invites in a good way.
+- It seems to mix sender and receiver reports, thus mixing data from two streams
+ - when does this happen, if at all?
+
+Todo
+----
+- Add support of outbound and inbound SDES. The SDES includes a stream identifier, CNAME.
+ When this changes, we have a different stream and need to restart the stats.
+ Should we add ability to produce multiple RTCP reports for one "call" and aggregate them?
+ The different parts might have different properties.
+- Check RTCP support for the p2p RTP bridge - today it doesn't work properly.
+
+Ideas and thoughts for the future
+---------------------------------
+- Asterisk propagates jitter and packet loss over a bridge (especially the p2p RTP bridge).
+ If the call is transfered on the OTHER side of the bridge, we have a new call with new
+ properties. Maybe events like this should generate a new SDES and reset RTCP?
+ Part A of the call can have very different properties than part B. If I have a call with
+ someone internally, that then transfers me to a call with someone on the Internet, the
+ call quality (jitter etc) will change dramatically. This will require some sort of CONTROL
+ packet over the bridge, informing about changes on the other side of the bridge (masq).
+- Can we have some sort of ring buffer for the latest RTCP reports for a device (peer)
+ and use that to determine the status of the connection to the peer?
+- Can we use the APP packet for relaying events in joined bridges, like meetme?
+
+
+Scenarios to test
+------------------
+- normal bridged call
+- RTP p2p bridged call
+-
Propchange: team/oej/pinefrog-1.4/README.pinefrog-rtcp
------------------------------------------------------------------------------
svn:eol-style = native
Propchange: team/oej/pinefrog-1.4/README.pinefrog-rtcp
------------------------------------------------------------------------------
svn:keywords = Author Date Id Revision
Propchange: team/oej/pinefrog-1.4/README.pinefrog-rtcp
------------------------------------------------------------------------------
svn:mime-type = text/plain
Modified: team/oej/pinefrog-1.4/main/channel.c
URL: http://svnview.digium.com/svn/asterisk/team/oej/pinefrog-1.4/main/channel.c?view=diff&rev=237655&r1=237654&r2=237655
==============================================================================
--- team/oej/pinefrog-1.4/main/channel.c (original)
+++ team/oej/pinefrog-1.4/main/channel.c Tue Jan 5 05:21:33 2010
@@ -999,12 +999,28 @@
return __ast_queue_frame(chan, fin, 1, NULL);
}
+static void set_hangupchannelvars(struct ast_channel *chan, const char *name)
+{
+ if (!chan || ast_strlen_zero(name)) {
+ return;
+ }
+
+ /* Set a channel variable */
+ pbx_builtin_setvar_helper(chan, "HANGUPCHANNEL", name);
+
+ /* Also set a cdr variable, that can be reached regardless of the cdr before h option */
+ if (chan->cdr) {
+ ast_cdr_setvar(chan->cdr, "hangupchannel", name, 0);
+ }
+}
+
/*! \brief Queue a hangup frame for channel */
int ast_queue_hangup(struct ast_channel *chan)
{
struct ast_frame f = { AST_FRAME_CONTROL, AST_CONTROL_HANGUP };
/* Yeah, let's not change a lock-critical value without locking */
if (!ast_channel_trylock(chan)) {
+ set_hangupchannelvars(chan, chan->name);
chan->_softhangup |= AST_SOFTHANGUP_DEV;
ast_channel_unlock(chan);
}
@@ -1460,6 +1476,8 @@
{
if (option_debug)
ast_log(LOG_DEBUG, "Soft-Hanging up channel '%s'\n", chan->name);
+
+ set_hangupchannelvars(chan, "system");
/* Inform channel driver that we need to be hung up, if it cares */
chan->_softhangup |= cause;
ast_queue_frame(chan, &ast_null_frame);
Modified: team/oej/pinefrog-1.4/main/rtp.c
URL: http://svnview.digium.com/svn/asterisk/team/oej/pinefrog-1.4/main/rtp.c?view=diff&rev=237655&r1=237654&r2=237655
==============================================================================
--- team/oej/pinefrog-1.4/main/rtp.c (original)
+++ team/oej/pinefrog-1.4/main/rtp.c Tue Jan 5 05:21:33 2010
@@ -64,12 +64,30 @@
#define RTCP_MIN_INTERVALMS 500 /*!< Min milli-seconds between RTCP reports we send */
#define RTCP_MAX_INTERVALMS 60000 /*!< Max milli-seconds between RTCP reports we send */
-#define RTCP_PT_FUR 192
-#define RTCP_PT_SR 200
-#define RTCP_PT_RR 201
-#define RTCP_PT_SDES 202
-#define RTCP_PT_BYE 203
-#define RTCP_PT_APP 204
+#define RTCP_PT_FUR 192 /*!< FIR - Full Intra-frame request */
+#define RTCP_PT_NACK 193 /*!< NACK - Negative acknowledgement */
+#define RTCP_PT_IJ 195 /*!< IJ - RFC 5450 Extended Inter-arrival jitter report */
+#define RTCP_PT_SR 200 /*!< SR - RFC 3550 Sender report */
+#define RTCP_PT_RR 201 /*!< RR - RFC 3550 Receiver report */
+#define RTCP_PT_SDES 202 /*!< SDES - Source Description */
+#define RTCP_PT_BYE 203 /*!< BYE - Goodbye */
+#define RTCP_PT_APP 204 /*!< APP - Application defined */
+#define RTCP_PT_RTPFB 205 /*!< RTPFB - Generic RTP feedback RFC 4585 */
+#define RTCP_PT_PSFB 206 /*!< PSFB - Payload specific data RFC 4585 */
+#define RTCP_PT_XR 207 /*!< XR - Extended report - RFC3611 */
+
+/*! \brief RFC 3550 RTCP SDES Item types */
+enum rtcp_sdes {
+ SDES_END = 0, /*!< End of SDES list */
+ SDES_CNAME = 1, /*!< Canonical name */
+ SDES_NAME = 2, /*!< User name */
+ SDES_EMAIL = 3, /*!< User's e-mail address */
+ SDES_PHONE = 4, /*!< User's phone number */
+ SDES_LOC = 5, /*!< Geographic user location */
+ SDES_TOOL = 6, /*!< Name of application or tool */
+ SDES_NOTE = 7, /*!< Notice about the source */
+ SDES_PRIV = 8, /*!< SDES Private extensions */
+};
#define RTP_MTU 1200
@@ -872,6 +890,8 @@
int position, i, packetwords;
int res;
struct sockaddr_in sin;
+ char sdestext[255];
+ unsigned int sdesheader, sdeslength, sdestype;
unsigned int rtcpdata[8192 + AST_FRIENDLY_OFFSET];
unsigned int *rtcpheader;
int pt;
@@ -893,7 +913,8 @@
len = sizeof(sin);
res = recvfrom(rtp->rtcp->s, rtcpdata + AST_FRIENDLY_OFFSET, sizeof(rtcpdata) - sizeof(unsigned int) * AST_FRIENDLY_OFFSET,
- 0, (struct sockaddr *)&sin, &len);
+ 0, (struct sockaddr *)&sin, &len);
+
rtcpheader = (unsigned int *)(rtcpdata + AST_FRIENDLY_OFFSET);
if (res < 0) {
@@ -905,7 +926,7 @@
return &ast_null_frame;
}
- packetwords = res / 4;
+ packetwords = res / 4; /* Each RTCP segment is 32 bits */
if (rtp->nat) {
/* Send to whoever sent to us */
@@ -914,41 +935,48 @@
((rtp->rtcp->altthem.sin_addr.s_addr != sin.sin_addr.s_addr) ||
(rtp->rtcp->altthem.sin_port != sin.sin_port))) {
memcpy(&rtp->rtcp->them, &sin, sizeof(rtp->rtcp->them));
- if (option_debug || rtpdebug)
+ if (option_debug || rtpdebug) {
ast_log(LOG_DEBUG, "RTCP NAT: Got RTCP from other end. Now sending to address %s:%d\n", ast_inet_ntoa(rtp->rtcp->them.sin_addr), ntohs(rtp->rtcp->them.sin_port));
- }
- }
-
- if (option_debug)
- ast_log(LOG_DEBUG, "Got RTCP report of %d bytes\n", res);
+ }
+ }
+ }
+
+ if (option_debug) {
+ ast_log(LOG_DEBUG, "Got RTCP report of %d bytes - %d messages\n", res, packetwords);
+ }
/* Process a compound packet */
position = 0;
while (position < packetwords) {
i = position;
+ ast_log(LOG_DEBUG, "***** Debug - position = %d\n", position);
+
length = ntohl(rtcpheader[i]);
+
+ /* Packet type */
pt = (length & 0xff0000) >> 16;
rc = (length & 0x1f000000) >> 24;
length &= 0xffff;
if ((i + length) > packetwords) {
- ast_log(LOG_WARNING, "RTCP Read too short\n");
+ ast_log(LOG_WARNING, "RTCP Read too short - position %d\n", i);
return &ast_null_frame;
}
if (rtcp_debug_test_addr(&sin)) {
- ast_verbose("\n\nGot RTCP from %s:%d\n", ast_inet_ntoa(sin.sin_addr), ntohs(sin.sin_port));
- ast_verbose("PT: %d(%s)\n", pt, (pt == 200) ? "Sender Report" : (pt == 201) ? "Receiver Report" : (pt == 192) ? "H.261 FUR" : "Unknown");
- ast_verbose("Reception reports: %d\n", rc);
- ast_verbose("SSRC of sender: %u\n", rtcpheader[i + 1]);
+ ast_verbose("\n-- Got RTCP from %s:%d\n", ast_inet_ntoa(sin.sin_addr), ntohs(sin.sin_port));
+ ast_verbose(" PT: %d(%s)", pt, (pt == 200) ? "Sender Report" : (pt == 201) ? "Receiver Report" : (pt == 192) ? "H.261 FUR" : "Other");
+ ast_verbose(" Reception reports: %d\n", rc);
+ ast_verbose(" SSRC of packet sender: %u", rtcpheader[i + 1]);
+ ast_verbose(" (Position %d of %d)\n", i, packetwords);
}
i += 2; /* Advance past header and ssrc */
-
- switch (pt) {
+
+ switch (pt) { /* Find the RTCP Packet type */
case RTCP_PT_SR:
- gettimeofday(&rtp->rtcp->rxlsr,NULL); /* To be able to populate the dlsr */
- rtp->rtcp->spc = ntohl(rtcpheader[i+3]);
+ gettimeofday(&rtp->rtcp->rxlsr, NULL); /* To be able to populate the dlsr */
+ rtp->rtcp->spc = ntohl(rtcpheader[i + 3]);
rtp->rtcp->soc = ntohl(rtcpheader[i + 4]);
rtp->rtcp->themrxlsr = ((ntohl(rtcpheader[i]) & 0x0000ffff) << 16) | ((ntohl(rtcpheader[i + 1]) & 0xffff0000) >> 16); /* Going to LSR in RR*/
@@ -956,8 +984,9 @@
ast_verbose("NTP timestamp: %lu.%010lu\n", (unsigned long) ntohl(rtcpheader[i]), (unsigned long) ntohl(rtcpheader[i + 1]) * 4096);
ast_verbose("RTP timestamp: %lu\n", (unsigned long) ntohl(rtcpheader[i + 2]));
ast_verbose("SPC: %lu\tSOC: %lu\n", (unsigned long) ntohl(rtcpheader[i + 3]), (unsigned long) ntohl(rtcpheader[i + 4]));
+ ast_verbose("RC (number of reports) %d\n", rc);
}
- i += 5;
+ i += 5; /* Sender's report is five bytes */
if (rc < 1)
break;
/* Intentional fall through */
@@ -975,10 +1004,10 @@
/* Convert end to end delay to usec (keeping the calculation in 64bit space)
sess->ee_delay = (eedelay * 1000) / 65536; */
if (rtt < 4294) {
- rtt = (rtt * 1000000) >> 16;
+ rtt = (rtt * 1000000) >> 16;
} else {
- rtt = (rtt * 1000) >> 16;
- rtt *= 1000;
+ rtt = (rtt * 1000) >> 16;
+ rtt *= 1000;
}
rtt = rtt / 1000.;
rttsec = rtt / 1000.;
@@ -1008,15 +1037,16 @@
ast_verbose(" Highest sequence number: %ld\n", (long) (ntohl(rtcpheader[i + 2]) & 0xffff));
ast_verbose(" Sequence number cycles: %ld\n", (long) (ntohl(rtcpheader[i + 2]) & 0xffff) >> 16);
ast_verbose(" Interarrival jitter: %u\n", rtp->rtcp->reported_jitter);
- ast_verbose(" Last SR(our NTP): %lu.%010lu\n",(unsigned long) ntohl(rtcpheader[i + 4]) >> 16,((unsigned long) ntohl(rtcpheader[i + 4]) << 16) * 4096);
- ast_verbose(" DLSR: %4.4f (sec)\n",ntohl(rtcpheader[i + 5])/65536.0);
+ ast_verbose(" Last SR (our NTP): %lu.%010lu\n", (unsigned long) ntohl(rtcpheader[i + 4]) >> 16,((unsigned long) ntohl(rtcpheader[i + 4]) << 16) * 4096);
+ ast_verbose(" DLSR: %4.4f (sec)\n", ntohl(rtcpheader[i + 5])/65536.0);
if (rtt)
ast_verbose(" RTT: %lu(sec)\n", (unsigned long) rtt);
}
break;
case RTCP_PT_FUR:
- if (rtcp_debug_test_addr(&sin))
+ if (rtcp_debug_test_addr(&sin)) {
ast_verbose("Received an RTCP Fast Update Request\n");
+ }
rtp->f.frametype = AST_FRAME_CONTROL;
rtp->f.subclass = AST_CONTROL_VIDUPDATE;
rtp->f.datalen = 0;
@@ -1026,12 +1056,46 @@
f = &rtp->f;
break;
case RTCP_PT_SDES:
+ sdesheader = ntohl(rtcpheader[i]);
+ sdeslength = (sdesheader & 0xff0000) >> 16;
+ sdestype = (sdesheader & 0x800000) >> 16;
+ if (rtcp_debug_test_addr(&sin)) {
+ ast_verbose("Received an SDES from %s:%d (Type %u, Length %u)\n", ast_inet_ntoa(rtp->rtcp->them.sin_addr), ntohs(rtp->rtcp->them.sin_port), sdestype, sdeslength);
+ }
+
+// /*! \brief RFC 3550 RTCP SDES Item types */
+// enum rtcp_sdes {
+ // SDES_END = 0, /*!< End of SDES list */
+ // SDES_CNAME = 1, /*!< Canonical name */
+ // SDES_NAME = 2, /*!< User name */
+ // SDES_EMAIL = 3, /*!< User's e-mail address */
+ // SDES_PHONE = 4, /*!< User's phone number */
+ // SDES_LOC = 5, /*!< Geographic user location */
+ // SDES_TOOL = 6, /*!< Name of application or tool */
+ // SDES_NOTE = 7, /*!< Notice about the source */
+ // SDES_PRIV = 8, /*!< SDES Private extensions */
+// };
+
+ break;
+ case RTCP_PT_NACK:
if (rtcp_debug_test_addr(&sin))
- ast_verbose("Received an SDES from %s:%d\n", ast_inet_ntoa(rtp->rtcp->them.sin_addr), ntohs(rtp->rtcp->them.sin_port));
+ ast_verbose("Received a RTCP NACK from %s:%d\n", ast_inet_ntoa(rtp->rtcp->them.sin_addr), ntohs(rtp->rtcp->them.sin_port));
break;
case RTCP_PT_BYE:
if (rtcp_debug_test_addr(&sin))
- ast_verbose("Received a BYE from %s:%d\n", ast_inet_ntoa(rtp->rtcp->them.sin_addr), ntohs(rtp->rtcp->them.sin_port));
+ ast_verbose("Received a RTCP BYE from %s:%d\n", ast_inet_ntoa(rtp->rtcp->them.sin_addr), ntohs(rtp->rtcp->them.sin_port));
+ break;
+ case RTCP_PT_XR:
+ if (rtcp_debug_test_addr(&sin))
+ ast_verbose("Received a RTCP Extended Report (XR) packet from %s:%d\n", ast_inet_ntoa(rtp->rtcp->them.sin_addr), ntohs(rtp->rtcp->them.sin_port));
+ break;
+ case RTCP_PT_APP:
+ if (rtcp_debug_test_addr(&sin))
+ ast_verbose("Received a RTCP APP packet from %s:%d\n", ast_inet_ntoa(rtp->rtcp->them.sin_addr), ntohs(rtp->rtcp->them.sin_port));
+ break;
+ case RTCP_PT_IJ:
+ if (rtcp_debug_test_addr(&sin))
+ ast_verbose("Received a RTCP IJ from %s:%d\n", ast_inet_ntoa(rtp->rtcp->them.sin_addr), ntohs(rtp->rtcp->them.sin_port));
break;
default:
if (option_debug)
@@ -1039,10 +1103,12 @@
break;
}
position += (length + 1);
- }
+ } /* While */
+
+ return f;
+}
+
- return f;
-}
static void sanitize_tv(struct timeval *tv)
{
Modified: team/oej/pinefrog-1.4/res/res_features.c
URL: http://svnview.digium.com/svn/asterisk/team/oej/pinefrog-1.4/res/res_features.c?view=diff&rev=237655&r1=237654&r2=237655
==============================================================================
--- team/oej/pinefrog-1.4/res/res_features.c (original)
+++ team/oej/pinefrog-1.4/res/res_features.c Tue Jan 5 05:21:33 2010
@@ -2001,6 +2001,7 @@
if (config->end_bridge_callback) {
config->end_bridge_callback(config->end_bridge_callback_data);
}
+
if (!ast_test_flag(&(config->features_caller),AST_FEATURE_NO_H_EXTEN) &&
ast_exists_extension(chan, chan->context, "h", 1, chan->cid.cid_num)) {
More information about the asterisk-commits
mailing list