[asterisk-commits] oej: branch oej/pinefrog-1.4 r238580 - in /team/oej/pinefrog-1.4: channels/ i...
SVN commits to the Asterisk project
asterisk-commits at lists.digium.com
Fri Jan 8 10:02:36 CST 2010
Author: oej
Date: Fri Jan 8 10:02:32 2010
New Revision: 238580
URL: http://svnview.digium.com/svn/asterisk?view=rev&rev=238580
Log:
A lot of unstructured updates to various stuff, a lot of it not tested.
But I'm really making progress here.
Thanks to Eduardo for finding the bug in chan_sip.c. Keep them bug reports coming :-)
Modified:
team/oej/pinefrog-1.4/channels/chan_sip.c
team/oej/pinefrog-1.4/include/asterisk/rtp.h
team/oej/pinefrog-1.4/main/rtp.c
team/oej/pinefrog-1.4/utils/Makefile
Modified: team/oej/pinefrog-1.4/channels/chan_sip.c
URL: http://svnview.digium.com/svn/asterisk/team/oej/pinefrog-1.4/channels/chan_sip.c?view=diff&rev=238580&r1=238579&r2=238580
==============================================================================
--- team/oej/pinefrog-1.4/channels/chan_sip.c (original)
+++ team/oej/pinefrog-1.4/channels/chan_sip.c Fri Jan 8 10:02:32 2010
@@ -18672,7 +18672,7 @@
default_qualify = 0;
}
} else if (!strcasecmp(v->name, "rtcpevents")) {
- global_callevents = ast_true(v->value);
+ global_rtcpevents = ast_true(v->value);
} else if (!strcasecmp(v->name, "callevents")) {
global_callevents = ast_true(v->value);
} else if (!strcasecmp(v->name, "maxcallbitrate")) {
Modified: team/oej/pinefrog-1.4/include/asterisk/rtp.h
URL: http://svnview.digium.com/svn/asterisk/team/oej/pinefrog-1.4/include/asterisk/rtp.h?view=diff&rev=238580&r1=238579&r2=238580
==============================================================================
--- team/oej/pinefrog-1.4/include/asterisk/rtp.h (original)
+++ team/oej/pinefrog-1.4/include/asterisk/rtp.h Fri Jan 8 10:02:32 2010
@@ -78,17 +78,21 @@
};
struct ast_rtp_quality {
- unsigned int local_ssrc; /* Our SSRC */
- unsigned int local_lostpackets; /* Our lost packets */
- double local_jitter; /* Our calculated jitter */
- unsigned int local_count; /* Number of received packets */
- unsigned int remote_ssrc; /* Their SSRC */
- unsigned int remote_lostpackets; /* Their lost packets */
- double remote_jitter; /* Their reported jitter */
- unsigned int remote_count; /* Number of transmitted packets */
- double rtt; /* Round trip time */
- int lasttxformat;
- int lastrxformat;
+ unsigned int local_ssrc; /*!< Our SSRC */
+ unsigned int local_lostpackets; /*!< Our lost packets */
+ double local_jitter; /*!< Our calculated jitter */
+ double local_jitter_max; /*!< Our calculated jitter */
+ double local_jitter_min; /*!< Our calculated jitter */
+ unsigned int local_count; /*!< Number of received packets */
+ unsigned int remote_ssrc; /*!< Their SSRC */
+ unsigned int remote_lostpackets; /*!< Their lost packets */
+ double remote_jitter; /*!< Their reported jitter */
+ unsigned int remote_count; /*!< Number of transmitted packets */
+ double rtt; /*!< Round trip time */
+ double rttmax; /*!< Max observed round trip time */
+ double rttmin; /*!< Max observed round trip time */
+ int lasttxformat; /*!< Last used codec on transmitted stream */
+ int lastrxformat; /*!< Last used codec on received stream */
};
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=238580&r1=238579&r2=238580
==============================================================================
--- team/oej/pinefrog-1.4/main/rtp.c (original)
+++ team/oej/pinefrog-1.4/main/rtp.c Fri Jan 8 10:02:32 2010
@@ -178,10 +178,12 @@
struct timeval dtmfmute;
struct ast_smoother *smoother;
int *ioid;
+ int *ioidrtcp;
unsigned short seqno; /*!< Sequence number, RFC 3550, page 13. */
unsigned short rxseqno;
struct sched_context *sched;
- struct io_context *io;
+ struct io_context *io; /*!< for RTP callback */
+ struct io_context *iortcp; /*!< for RTCP callback */
void *data;
ast_rtp_callback callback;
ast_mutex_t bridge_lock;
@@ -200,11 +202,14 @@
/* Forward declarations */
static int ast_rtcp_write(const void *data);
static void timeval2ntp(struct timeval tv, unsigned int *msw, unsigned int *lsw);
-static int ast_rtcp_write_sr(const void *data);
-static int ast_rtcp_write_rr(const void *data);
+static int ast_rtcp_write_sr(const void *data, int goodbye);
+static int ast_rtcp_write_rr(const void *data, int goodbye);
static unsigned int ast_rtcp_calc_interval(struct ast_rtp *rtp);
static int ast_rtp_senddigit_continuation(struct ast_rtp *rtp);
int ast_rtp_senddigit_end(struct ast_rtp *rtp, char digit);
+static struct ast_frame *ast_rtcp_read_fd(int fd, struct ast_rtp *rtp);
+static int ast_rtcp_write_empty(struct ast_rtp *rtp, int fd);
+static int p2p_rtcp_callback(int *id, int fd, short events, void *cbdata);
#define FLAG_3389_WARNING (1 << 0)
#define FLAG_NAT_ACTIVE (3 << 1)
@@ -230,7 +235,9 @@
struct ast_rtcp {
int s; /*!< Socket */
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 sockaddr_in us; /*!< Socket representation of the local endpoint. */
struct sockaddr_in them; /*!< Socket representation of the remote endpoint. */
struct sockaddr_in altthem; /*!< Alternate source for RTCP */
@@ -248,12 +255,23 @@
double accumulated_transit; /*!< accumulated a-dlsr-lsr */
double rtt; /*!< Last reported rtt */
unsigned int reported_jitter; /*!< The contents of their last jitter entry in the RR */
+ double reported_maxjitter; /*!< The contents of their last jitter entry in the RR */
+ double reported_minjitter; /*!< The contents of their last jitter entry in the RR */
+ unsigned int reported_jitter_count;
unsigned int reported_lost; /*!< Reported lost packets in their RR */
+ double reported_maxlost;
+ double reported_minlost;
+ double rxlost;
+ double maxrxlost;
+ double minrxlost;
+ unsigned int rxlost_count;
char quality[AST_MAX_USER_FIELD];
double maxrxjitter;
double minrxjitter;
+ unsigned int rxjitter_count;
double maxrtt;
double minrtt;
+ unsigned int rtt_count;
int sendfur;
};
@@ -552,6 +570,22 @@
return (subclass == AST_FORMAT_G722) ? 8000 : ast_format_rate(subclass);
}
+/*! \brief Schedule RTCP transmissions for RTP channel */
+static void ast_rtcp_schedule(struct ast_rtp *rtp)
+{
+ /* Do not schedule RR if RTCP isn't run */
+ if (rtp->rtcp && rtp->rtcp->them.sin_addr.s_addr && rtp->rtcp->schedid < 1) {
+ /* Schedule transmission of Receiver Report */
+ ast_rtcp_write_empty(rtp, rtp->rtcp->s);
+ rtp->rtcp->schedid = ast_sched_add(rtp->sched, ast_rtcp_calc_interval(rtp), ast_rtcp_write, rtp);
+ ast_log(LOG_DEBUG, "-------- SCHEDULING RTCP reports!!!\n");
+ } else {
+ //ast_log(LOG_DEBUG, "----- NOT SCHEDULING RTCP - RTCP %s RTCP address %s schedid %d\n",
+ //rtp->rtcp ? "yes" : "no",
+ //rtp->rtcp->them.sin_addr.s_addr ? "yes" : "no", rtp->rtcp->schedid);
+ }
+}
+
unsigned int ast_rtcp_calc_interval(struct ast_rtp *rtp)
{
unsigned int interval;
@@ -888,7 +922,20 @@
return 1;
}
+static int p2p_rtcp_callback(int *id, int fd, short events, void *cbdata)
+{
+ struct ast_rtp *rtp = cbdata;
+ ast_rtcp_read_fd(fd, rtp);
+ /* For now, skip any frames that is output. Which is bad for FUR's, but well. DEBUG */
+ return 1;
+}
+
struct ast_frame *ast_rtcp_read(struct ast_rtp *rtp)
+{
+ return ast_rtcp_read_fd(rtp->rtcp->s, rtp);
+}
+
+static struct ast_frame *ast_rtcp_read_fd(int fd, struct ast_rtp *rtp)
{
socklen_t len;
int position, i, j, packetwords;
@@ -916,7 +963,7 @@
len = sizeof(sin);
- res = recvfrom(rtp->rtcp->s, rtcpdata + AST_FRIENDLY_OFFSET, sizeof(rtcpdata) - sizeof(unsigned int) * AST_FRIENDLY_OFFSET,
+ res = recvfrom(fd, rtcpdata + AST_FRIENDLY_OFFSET, sizeof(rtcpdata) - sizeof(unsigned int) * AST_FRIENDLY_OFFSET,
0, (struct sockaddr *)&sin, &len);
rtcpheader = (unsigned int *)(rtcpdata + AST_FRIENDLY_OFFSET);
@@ -961,49 +1008,62 @@
length = ntohl(rtcpheader[i]);
- /* Packet type */
- pt = (length & 0xff0000) >> 16;
- rc = (length & 0x1f000000) >> 24;
+ pt = (length & 0xff0000) >> 16; /* Packet type */
+ rc = (length & 0x1f000000) >> 24; /* Number of chunks, i.e. streams reported */
length &= 0xffff;
if ((i + length) > packetwords) {
- ast_log(LOG_WARNING, "RTCP Read too short - position %d\n", i);
- return &ast_null_frame;
+ ast_log(LOG_WARNING, "RTCP Read too short - packet type %d position %d\n", pt, i);
+ return f;
}
if (rtcp_debug_test_addr(&sin)) {
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(" Length : %d\n", length);
- ast_verbose(" Reception reports: %d\n", rc);
- ast_verbose(" SSRC of packet sender: %u", rtcpheader[i + 1]);
+ ast_verbose(" Length : %d Chunks: %d\n", length, rc);
+ ast_verbose(" SSRC of packet sender: %u (%x)", rtcpheader[i + 1], rtcpheader[i + 1]);
ast_verbose(" (Position %d of %d)\n", i, packetwords);
+ if (rc == 0) {
+ ast_verbose(" Empty - no reports! \n");
+ }
}
i += 2; /* Advance past header and ssrc */
+ if (rc == 0) { /* We're receiving a report with no reports, which is ok */
+ position += (length + 1);
+ continue;
+ }
switch (pt) { /* Find the RTCP Packet type */
- case RTCP_PT_SR:
+ case RTCP_PT_SR: /* Sender's report - about what they have sent us */
+ if (rtcp_debug_test_addr(&sin)) {
+ ast_verbose(" - RTCP SR (sender report) from %s:%d\n", ast_inet_ntoa(rtp->rtcp->them.sin_addr), ntohs(rtp->rtcp->them.sin_port));
+ }
+ /* Don't handle multiple reception reports (rc > 1) yet */
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->spc = ntohl(rtcpheader[i + 3]); /* Sender packet count */
+ rtp->rtcp->soc = ntohl(rtcpheader[i + 4]); /* Sender octet count */
+
rtp->rtcp->themrxlsr = ((ntohl(rtcpheader[i]) & 0x0000ffff) << 16) | ((ntohl(rtcpheader[i + 1]) & 0xffff0000) >> 16); /* Going to LSR in RR*/
if (rtcp_debug_test_addr(&sin)) {
- 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);
+ 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; /* Sender's report is five bytes */
+ i += 5; /* Sender's info report is five bytes */
if (rc < 1)
break;
- /* Intentional fall through */
- case RTCP_PT_RR:
+ /* Intentional fall through - the report blocks are the same for RR and SR */
+ case RTCP_PT_RR: /* Receiver report - data about what we have sent to them */
+ if (rtcp_debug_test_addr(&sin)) {
+ ast_verbose("Received a RTCP RR (receiver report) from %s:%d\n", ast_inet_ntoa(rtp->rtcp->them.sin_addr), ntohs(rtp->rtcp->them.sin_port));
+ }
/* Don't handle multiple reception reports (rc > 1) yet */
/* Calculate RTT per RFC */
gettimeofday(&now, NULL);
timeval2ntp(now, &msw, &lsw);
+ /* Get timing */
if (ntohl(rtcpheader[i + 4]) && ntohl(rtcpheader[i + 5])) { /* We must have the LSR && DLSR */
comp = ((msw & 0xffff) << 16) | ((lsw & 0xffff0000) >> 16);
lsr = ntohl(rtcpheader[i + 4]);
@@ -1024,10 +1084,11 @@
if (comp - dlsr >= lsr) {
rtp->rtcp->accumulated_transit += rttsec;
rtp->rtcp->rtt = rttsec;
- if (rtp->rtcp->maxrtt<rttsec)
+ if (rtp->rtcp->maxrtt < rttsec)
rtp->rtcp->maxrtt = rttsec;
- if (rtp->rtcp->minrtt>rttsec)
+ if (rtp->rtcp->minrtt > rttsec || rtp->rtcp->minrtt == 0) {
rtp->rtcp->minrtt = rttsec;
+ }
} else if (rtcp_debug_test_addr(&sin)) {
ast_verbose("Internal RTCP NTP clock skew detected: "
"lsr=%u, now=%u, dlsr=%u (%d:%03dms), "
@@ -1039,17 +1100,25 @@
}
rtp->rtcp->reported_jitter = ntohl(rtcpheader[i + 3]);
+ if (rtp->rtcp->reported_jitter > rtp->rtcp->reported_maxjitter) {
+ rtp->rtcp->reported_maxjitter = rtp->rtcp->reported_jitter;
+ } else if (rtp->rtcp->reported_jitter < rtp->rtcp->reported_minjitter || rtp->rtcp->reported_minjitter == 0) {
+ rtp->rtcp->reported_minjitter = rtp->rtcp->reported_jitter;
+ }
rtp->rtcp->reported_lost = ntohl(rtcpheader[i + 1]) & 0xffffff;
if (rtcp_debug_test_addr(&sin)) {
ast_verbose(" Fraction lost: %ld\n", (((long) ntohl(rtcpheader[i + 1]) & 0xff000000) >> 24));
ast_verbose(" Packets lost so far: %d\n", rtp->rtcp->reported_lost);
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(" Interarrival jitter: %u Max %u Min %u\n", rtp->rtcp->reported_jitter,
+ rtp->rtcp->reported_maxjitter, rtp->rtcp->reported_minjitter);
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);
+ ast_verbose(" RTT: %lu(sec) Max %lu Min %lu\n", (unsigned long) rtt,
+ (unsigned long) rtp->rtcp->maxrtt,
+ (unsigned long) rtp->rtcp->minrtt );
}
break;
case RTCP_PT_FUR:
@@ -1074,7 +1143,6 @@
In the SDES message, there can be several items, ending with SDES_END
The length of the all items is length - header
Chunk starts on a 32-bit boundary and needs padding by 0's
-
the "rc" variable contains the number of chunks
When we start, we're beyond the SSRC and starts with SDES items in the
@@ -1098,39 +1166,55 @@
}
switch (sdestype) {
case SDES_CNAME:
+ if (!ast_strlen_zero(rtp->rtcp->theircname)) {
+ if (strncmp(rtp->rtcp->theircname, sdes, sdeslength)) {
+ ast_log(LOG_WARNING, "New RTP stream received (new RTCP CNAME for session. Old name: %s\n", rtp->rtcp->theircname);
+ }
+ }
strncpy(rtp->rtcp->theircname, sdes, sdeslength);
rtp->rtcp->theircname[sdeslength] = '\0';
+ rtp->rtcp->theircnamelength = sdeslength;
if (rtcp_debug_test_addr(&sin)) {
ast_verbose(" --- SDES CNAME (utf8) %s\n", rtp->rtcp->theircname);
}
break;
case SDES_EMAIL:
+ if (rtcp_debug_test_addr(&sin)) {
+ ast_verbose(" --- SDES EMAIL \n");
+ }
break;
case SDES_PHONE:
+ if (rtcp_debug_test_addr(&sin)) {
+ ast_verbose(" --- SDES PHONE \n");
+ }
break;
case SDES_LOC:
+ if (rtcp_debug_test_addr(&sin)) {
+ ast_verbose(" --- SDES LOC \n");
+ }
break;
case SDES_NOTE:
+ if (rtcp_debug_test_addr(&sin)) {
+ ast_verbose(" --- SDES NOTE \n");
+ }
break;
case SDES_PRIV:
+ if (rtcp_debug_test_addr(&sin)) {
+ ast_verbose(" --- SDES PRIV \n");
+ }
+ break;
+ case SDES_END:
+ if (rtcp_debug_test_addr(&sin)) {
+ ast_verbose(" --- SDES END \n");
+ }
break;
}
- j += sdeslength; /* Header (1 byte) + length */
+ j += 2 + sdeslength; /* Header (1 byte) + length */
sdes += sdeslength;
+ if (sdestype == SDES_END) {
+ break; /* The while loop */
+ }
}
-
-// /*! \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:
@@ -1201,6 +1285,7 @@
}
gettimeofday(&now,NULL);
+
/* rxcore is the mapping between the RTP timestamp and _our_ real time from gettimeofday() */
tv->tv_sec = rtp->rxcore.tv_sec + timestamp / rate;
tv->tv_usec = rtp->rxcore.tv_usec + (timestamp % rate) * 125;
@@ -1214,10 +1299,18 @@
if (d<0)
d=-d;
rtp->rxjitter += (1./16.) * (d - rtp->rxjitter);
- if (rtp->rtcp && rtp->rxjitter > rtp->rtcp->maxrxjitter)
+ if (!rtp->rtcp) {
+ return;
+ }
+
+ if (rtp->rxjitter > rtp->rtcp->maxrxjitter)
rtp->rtcp->maxrxjitter = rtp->rxjitter;
- if (rtp->rtcp && rtp->rxjitter < rtp->rtcp->minrxjitter)
+ if (rtp->rtcp->rxjitter_count == 1) {
rtp->rtcp->minrxjitter = rtp->rxjitter;
+ }
+ if (rtp->rxjitter < rtp->rtcp->minrxjitter)
+ rtp->rtcp->minrxjitter = rtp->rxjitter;
+ rtp->rtcp->rxjitter_count++;
}
/*! \brief Perform a Packet2Packet RTP write */
@@ -1271,6 +1364,8 @@
return 0;
} else if (rtp_debug_test_addr(&bridged->them))
ast_verbose("Sent RTP P2P packet to %s:%u (type %-2.2d, len %-6.6u)\n", ast_inet_ntoa(bridged->them.sin_addr), ntohs(bridged->them.sin_port), bridged_payload, len - hdrlen);
+ rtp->txcount++;
+ //SKREP rtp->lasttxformat = rtpPT;
return 0;
}
@@ -1408,11 +1503,9 @@
rtp->seedrxseqno = seqno;
}
- /* Do not schedule RR if RTCP isn't run */
- if (rtp->rtcp && rtp->rtcp->them.sin_addr.s_addr && rtp->rtcp->schedid < 1) {
- /* Schedule transmission of Receiver Report */
- rtp->rtcp->schedid = ast_sched_add(rtp->sched, ast_rtcp_calc_interval(rtp), ast_rtcp_write, rtp);
- }
+ /* Schedule RTCP report transmissions if possible */
+ ast_rtcp_schedule(rtp);
+
if ( (int)rtp->lastrxseqno - (int)seqno > 100) /* if so it would indicate that the sender cycled; allow for misordering */
rtp->cycles += RTP_SEQ_MOD;
@@ -2160,6 +2253,7 @@
if (callbackmode) {
rtp->ioid = ast_io_add(rtp->io, rtp->s, rtpread, AST_IO_IN, rtp);
ast_set_flag(rtp, FLAG_CALLBACK_MODE);
+ rtp->ioidrtcp = ast_io_add(rtp->iortcp, rtp->rtcp->s, p2p_rtcp_callback, AST_IO_IN, rtp);
}
ast_rtp_pt_default(rtp);
return rtp;
@@ -2180,6 +2274,7 @@
return;
}
ast_copy_string(rtp->rtcp->ourcname, cname, length > 255 ? 255 : length);
+ rtp->rtcp->ourcnamelength = length;
ast_log(LOG_DEBUG, "--- Copied CNAME %s to RTCP structure (length %d)\n", cname, (int) length);
}
@@ -2271,6 +2366,9 @@
memset(&rtp->them.sin_addr, 0, sizeof(rtp->them.sin_addr));
memset(&rtp->them.sin_port, 0, sizeof(rtp->them.sin_port));
if (rtp->rtcp) {
+ /* Send RTCP goodbye packet */
+ ast_log(LOG_DEBUG, "----- REQUESTING GOODBYE RTCP \n");
+ ast_rtcp_write_sr((const void *) rtp, 1);
memset(&rtp->rtcp->them.sin_addr, 0, sizeof(rtp->rtcp->them.sin_addr));
memset(&rtp->rtcp->them.sin_port, 0, sizeof(rtp->rtcp->them.sin_port));
}
@@ -2348,27 +2446,40 @@
{
if (rtcp_debug_test_addr(&rtp->them) || rtcpstats) {
/*Print some info on the call here */
- ast_verbose(" RTP-stats\n");
+ ast_verbose(" RTP-stats\n");
ast_verbose("* Our Receiver:\n");
- ast_verbose(" SSRC: %u\n", rtp->themssrc);
- ast_verbose(" Received packets: %u\n", rtp->rxcount);
- ast_verbose(" Lost packets: %u\n", rtp->rtcp ? (rtp->rtcp->expected_prior - rtp->rtcp->received_prior) : 0);
- ast_verbose(" Jitter: %.4f\n", rtp->rxjitter);
- ast_verbose(" Transit: %.4f\n", rtp->rxtransit);
- ast_verbose(" RR-count: %u\n", rtp->rtcp ? rtp->rtcp->rr_count : 0);
+ ast_verbose(" SSRC: %u\n", rtp->themssrc);
+ ast_verbose(" CNAME: %s\n", rtp->rtcp ? rtp->rtcp->theircname : "");
+ ast_verbose(" Received packets: %u\n", rtp->rxcount);
+ ast_verbose(" Lost packets: %u\n", rtp->rtcp ? (rtp->rtcp->expected_prior - rtp->rtcp->received_prior) : 0);
+ ast_verbose(" Jitter: %.4f\n", rtp->rxjitter);
+ ast_verbose(" Transit: %.4f\n", rtp->rxtransit);
+ ast_verbose(" RR-count: %u\n", rtp->rtcp ? rtp->rtcp->rr_count : 0);
+
ast_verbose("* Our Sender:\n");
- ast_verbose(" SSRC: %u\n", rtp->ssrc);
- ast_verbose(" Sent packets: %u\n", rtp->txcount);
- ast_verbose(" Lost packets: %u\n", rtp->rtcp ? rtp->rtcp->reported_lost : 0);
- ast_verbose(" Jitter: %u\n", rtp->rtcp ? (rtp->rtcp->reported_jitter / (unsigned int)65536.0) : 0);
- ast_verbose(" SR-count: %u\n", rtp->rtcp ? rtp->rtcp->sr_count : 0);
- ast_verbose(" RTT: %f\n", rtp->rtcp ? rtp->rtcp->rtt : 0);
+ ast_verbose(" SSRC: %u\n", rtp->ssrc);
+ ast_verbose(" CNAME: %s\n", rtp->rtcp ? rtp->rtcp->ourcname : "");
+ ast_verbose(" Sent packets: %u\n", rtp->txcount);
+ ast_verbose(" Lost packets: %u\n", rtp->rtcp ? rtp->rtcp->reported_lost : 0);
+ ast_verbose(" Jitter: %u\n", rtp->rtcp ? (rtp->rtcp->reported_jitter / (unsigned int)65536.0) : 0);
+ ast_verbose(" SR-count: %u\n", rtp->rtcp ? rtp->rtcp->sr_count : 0);
+ ast_verbose(" RTT: %lu\n", rtp->rtcp ? (unsigned long) rtp->rtcp->rtt : 0);
+ ast_verbose(" RTT Max: %lu\n", rtp->rtcp ? (unsigned long) rtp->rtcp->maxrtt : 0);
+ ast_verbose(" RTT Min: %lu\n", rtp->rtcp ? (unsigned long) rtp->rtcp->minrtt : 0);
+
+ ast_verbose("* Media\n");
+ ast_verbose(" Last format sent: %s\n", ast_getformatname(rtp->lasttxformat));
+ ast_verbose(" Last format recv: %s\n", ast_getformatname(rtp->lastrxformat));
+
+ ast_verbose("\n");
}
if (rtp->smoother)
ast_smoother_free(rtp->smoother);
if (rtp->ioid)
ast_io_remove(rtp->io, rtp->ioid);
+ if (rtp->ioidrtcp)
+ ast_io_remove(rtp->iortcp, rtp->ioidrtcp);
if (rtp->s > -1)
close(rtp->s);
if (rtp->rtcp) {
@@ -2572,45 +2683,116 @@
return res;
}
-static int add_sdes_bodypart(struct ast_rtp *rtp, unsigned int *rtcp_packet, int len)
-{
- unsigned int *start = rtcp_packet;
- char *sdes;
- int cnamelen;
-
- rtcp_packet++; /* Move 32 bits ahead */
+/*! \brief Basically add SSRC */
+static int add_sdes_header(struct ast_rtp *rtp, unsigned int *rtcp_packet, int len)
+{
+ /* 2 is version, 1 is number of chunks, then RTCP packet type (SDES) and length */
+ *rtcp_packet = htonl((2 << 30) | (1 << 24) | (RTCP_PT_SDES << 16) | ((len/4)-1));
+
+ rtcp_packet++; /* Move 32 bits ahead for the header */
*rtcp_packet = htonl(rtp->ssrc); /* Our SSRC */
rtcp_packet ++;
- len += 8; /* Header + SSRC */
-
- ast_log(LOG_DEBUG, "----About to copy CNAME to SDES packet --- (len %d)\n", len);
+ /* Header + SSRC */
+ return len + 8;
+}
+
+static int add_sdes_bodypart(struct ast_rtp *rtp, unsigned int *rtcp_packet, int len, int type)
+{
+ int cnamelen;
+ int sdeslen = 0;
+ char *sdes;
sdes = (char *) rtcp_packet;
- cnamelen = (int) strlen(rtp->rtcp->ourcname);
-
- *sdes = SDES_CNAME;
- sdes++;
- *sdes = (char) cnamelen;
- sdes++;
- strncpy(sdes, rtp->rtcp->ourcname, cnamelen); /* NO terminating 0 */
- sdes+=cnamelen;
- *sdes = SDES_END; /* Terminating SDES packet */
-
- /* THere must be a multiple of four bytes in the packet */
- len += 2 + cnamelen + ((cnamelen +2) % 4 == 0 ? 0 : 4 - ((cnamelen + 2) % 4)) ;
- ast_log(LOG_DEBUG, "----our CNAME %s--- (cnamelen %d len %d)\n", rtp->rtcp->ourcname, cnamelen, len);
-
- /* 2 is version, 1 is number of chunks, then RTCP packet type (SDES) and length */
- *start = htonl((2 << 30) | (1 << 24) | (RTCP_PT_SDES << 16) | ((len/4)-1));
+ switch (type) {
+ case SDES_CNAME:
+ ast_log(LOG_DEBUG, "----About to copy CNAME to SDES packet --- (len %d)\n", len);
+
+ cnamelen = (int) strlen(rtp->rtcp->ourcname);
+
+ *sdes = SDES_CNAME;
+ sdes++;
+ *sdes = (char) cnamelen;
+ sdes++;
+ strncpy(sdes, rtp->rtcp->ourcname, cnamelen); /* NO terminating 0 */
+
+ /* THere must be a multiple of four bytes in the packet */
+ sdeslen = cnamelen;
+ ast_log(LOG_DEBUG, "----our CNAME %s--- (cnamelen %d len %d)\n", rtp->rtcp->ourcname, cnamelen, len);
+ break;
+ case SDES_END:
+ *sdes = SDES_END;
+ sdes++;
+ *sdes = (char) 0;
+ sdes++;
+ sdeslen = 2;
+ }
+ len += sdeslen + (sdeslen % 4 == 0 ? 0 : 4 - (sdeslen % 4)) ;
ast_log(LOG_DEBUG, "----Copied our CNAME to SDES packet --- (len %d)\n", len);
return len;
}
+/*! \brief Send emtpy RTCP receiver's report and SDES message
+ Mainly used to open NAT sessions */
+static int ast_rtcp_write_empty(struct ast_rtp *rtp, int fd)
+{
+ char bdata[512];
+ unsigned int *rtcpheader, *start;
+ int len, res;
+
+ if (!rtp || !rtp->rtcp) {
+ ast_log(LOG_DEBUG, "---- NOT sending empty RTCP packet\n");
+ return 0;
+ }
+ if (fd == -1) {
+ ast_log(LOG_DEBUG, "--- No file descriptor to use \n");
+ }
+
+ if (!rtp->rtcp->them.sin_addr.s_addr) { /* This'll stop rtcp for this rtp session */
+ ast_verbose("RTCP SR transmission error, rtcp halted\n");
+ AST_SCHED_DEL(rtp->sched, rtp->rtcp->schedid);
+ return 0;
+ }
+ ast_log(LOG_DEBUG, "---- About to send empty RTCP packet\n");
+ rtcpheader = (unsigned int *)bdata;
+ /* Add a RR header with no reports (chunks = 0) - The RFC says that it's always needed
+ first in a compound packet.
+ */
+ rtcpheader[0] = htonl((2 << 30) | (0 << 24) | (RTCP_PT_RR << 16) | 1);
+ rtcpheader[1] = htonl(rtp->ssrc);
+ len = 8;
+ start = &rtcpheader[len/4];
+ len +=8; /* SKip header for now */
+ len = add_sdes_bodypart(rtp, &rtcpheader[len/4], len, SDES_CNAME);
+ len = add_sdes_bodypart(rtp, &rtcpheader[len/4], len, SDES_END);
+ /* Now, add header when we know the actual length */
+ add_sdes_header(rtp, start, len);
+
+ res = sendto(fd, (unsigned int *)rtcpheader, len, 0, (struct sockaddr *)&rtp->rtcp->them, sizeof(rtp->rtcp->them));
+
+ if (res < 0) {
+ ast_log(LOG_ERROR, "RTCP RR transmission error, rtcp halted: %s\n",strerror(errno));
+ /* Remove the scheduler */
+ AST_SCHED_DEL(rtp->sched, rtp->rtcp->schedid);
+ return 0;
+ }
+
+ rtp->rtcp->rr_count++;
+
+ if (rtcp_debug_test_addr(&rtp->rtcp->them)) {
+ ast_verbose("\n* Sending Empty RTCP RR to %s:%d Our SSRC: %u\n",
+ ast_inet_ntoa(rtp->rtcp->them.sin_addr),
+ ntohs(rtp->rtcp->them.sin_port),
+ rtp->ssrc);
+ }
+
+ return res;
+}
+
/*! \brief Send RTCP sender's report */
-static int ast_rtcp_write_sr(const void *data)
+static int ast_rtcp_write_sr(const void *data, int goodbye)
{
struct ast_rtp *rtp = (struct ast_rtp *)data;
int res;
@@ -2618,7 +2800,7 @@
struct timeval now;
unsigned int now_lsw;
unsigned int now_msw;
- unsigned int *rtcpheader;
+ unsigned int *rtcpheader, *start;
unsigned int lost;
unsigned int extended;
unsigned int expected;
@@ -2629,8 +2811,7 @@
struct timeval dlsr;
char bdata[512];
- /* Commented condition is always not NULL if rtp->rtcp is not NULL */
- if (!rtp || !rtp->rtcp/* || (&rtp->rtcp->them.sin_addr == 0)*/)
+ if (!rtp || !rtp->rtcp)
return 0;
if (!rtp->rtcp->them.sin_addr.s_addr) { /* This'll stop rtcp for this rtp session */
@@ -2673,6 +2854,7 @@
rtcpheader[12] = htonl((((dlsr.tv_sec * 1000) + (dlsr.tv_usec / 1000)) * 65536) / 1000);
len += 24;
+ /* Set the header for sender's report */
rtcpheader[0] = htonl((2 << 30) | (1 << 24) | (RTCP_PT_SR << 16) | ((len/4)-1));
if (rtp->rtcp->sendfur) {
@@ -2682,9 +2864,24 @@
rtp->rtcp->sendfur = 0;
}
- len = add_sdes_bodypart(rtp, &rtcpheader[len/4], len);
-
-
+ start = &rtcpheader[len/4];
+ len +=8; /* SKip header for now */
+ len = add_sdes_bodypart(rtp, &rtcpheader[len/4], len, SDES_CNAME);
+ len = add_sdes_bodypart(rtp, &rtcpheader[len/4], len, SDES_END);
+ /* Now, add header when we know the actual length */
+ ast_log(LOG_DEBUG, "----- AFTER SENDING CNAME RTCP Len: %d \n", len);
+ add_sdes_header(rtp, start, len);
+
+ if (goodbye) {
+ ast_log(LOG_DEBUG, "----- SENDING GOODBYE RTCP Len: %d \n", len);
+ /* An additional RTCP block */
+ len+=4;
+ rtcpheader[len/4] = htonl((2 << 30) | (1 << 24) | (RTCP_PT_BYE << 16) | 1);
+ len += 4;
+ rtcpheader[len/4] = htonl(rtp->ssrc); /* Our SSRC */
+ len += 4;
+ ast_log(LOG_DEBUG, "----- SENT GOODBYE RTCP Len: %d \n", len);
+ }
res = sendto(rtp->rtcp->s, (unsigned int *)rtcpheader, len, 0, (struct sockaddr *)&rtp->rtcp->them, sizeof(rtp->rtcp->them));
if (res < 0) {
@@ -2703,6 +2900,7 @@
ast_verbose("* Sent RTCP SR to %s:%d\n", ast_inet_ntoa(rtp->rtcp->them.sin_addr), ntohs(rtp->rtcp->them.sin_port));
ast_verbose(" Our SSRC: %u\n", rtp->ssrc);
ast_verbose(" Sent(NTP): %u.%010u\n", (unsigned int)now.tv_sec, (unsigned int)now.tv_usec*4096);
+ ast_verbose(" Send NTP variant: %lu.%010lu\n", (unsigned long) ntohl(rtcpheader[2]),((unsigned long) ntohl(rtcpheader[3])) * 4096);
ast_verbose(" Sent(RTP): %u\n", rtp->lastts);
ast_verbose(" Sent packets: %u\n", rtp->txcount);
ast_verbose(" Sent octets: %u\n", rtp->txoctetcount);
@@ -2717,7 +2915,7 @@
}
/*! \brief Send RTCP recepient's report */
-static int ast_rtcp_write_rr(const void *data)
+static int ast_rtcp_write_rr(const void *data, int goodbye)
{
struct ast_rtp *rtp = (struct ast_rtp *)data;
int res;
@@ -2729,7 +2927,7 @@
unsigned int received_interval;
int lost_interval;
struct timeval now;
- unsigned int *rtcpheader;
+ unsigned int *rtcpheader, *start;
char bdata[1024];
struct timeval dlsr;
int fraction;
@@ -2751,6 +2949,8 @@
received_interval = rtp->rxcount - rtp->rtcp->received_prior;
rtp->rtcp->received_prior = rtp->rxcount;
lost_interval = expected_interval - received_interval;
+
+ rtp->rtcp->rxlost_count++;
if (expected_interval == 0 || lost_interval <= 0)
fraction = 0;
else
@@ -2774,13 +2974,13 @@
rtp->rtcp->sendfur = 0;
}
- /*! \note Insert SDES here. Probably should make SDES text equal to mimetypes[code].type (not subtype 'cos
- it can change mid call, and SDES can't) */
- rtcpheader[len/4] = htonl((2 << 30) | (1 << 24) | (RTCP_PT_SDES << 16) | 2);
- rtcpheader[(len/4)+1] = htonl(rtp->ssrc); /* Our SSRC */
- rtcpheader[(len/4)+2] = htonl(0x01 << 24); /* Empty for the moment */
- len += 12;
-
+ start = &rtcpheader[len/4];
+ len +=8; /* SKip header for now */
+ len = add_sdes_bodypart(rtp, &rtcpheader[len/4], len, SDES_CNAME);
+ len = add_sdes_bodypart(rtp, &rtcpheader[len/4], len, SDES_END);
+ /* Now, add header when we know the actual length */
+ add_sdes_header(rtp, start, len);
+
res = sendto(rtp->rtcp->s, (unsigned int *)rtcpheader, len, 0, (struct sockaddr *)&rtp->rtcp->them, sizeof(rtp->rtcp->them));
if (res < 0) {
@@ -2821,9 +3021,9 @@
return 0;
if (rtp->txcount > rtp->rtcp->lastsrtxcount)
- res = ast_rtcp_write_sr(data);
+ res = ast_rtcp_write_sr(data, 0);
else
- res = ast_rtcp_write_rr(data);
+ res = ast_rtcp_write_rr(data, 0);
return res;
}
@@ -2955,10 +3155,8 @@
rtp->txcount++;
rtp->txoctetcount +=(res - hdrlen);
- /* Do not schedule RR if RTCP isn't run */
- if (rtp->rtcp && rtp->rtcp->them.sin_addr.s_addr && rtp->rtcp->schedid < 1) {
- rtp->rtcp->schedid = ast_sched_add(rtp->sched, ast_rtcp_calc_interval(rtp), ast_rtcp_write, rtp);
- }
+ /* Schedule RTCP report transmissions if possible */
+ ast_rtcp_schedule(rtp);
}
if (rtp_debug_test_addr(&rtp->them))
@@ -3337,6 +3535,7 @@
/*! \brief P2P RTP Callback */
#ifdef P2P_INTENSE
+
static int p2p_rtp_callback(int *id, int fd, short events, void *cbdata)
{
int res = 0, hdrlen = 12;
@@ -3351,6 +3550,11 @@
len = sizeof(sin);
if ((res = recvfrom(fd, rtp->rawdata + AST_FRIENDLY_OFFSET, sizeof(rtp->rawdata) - AST_FRIENDLY_OFFSET, 0, (struct sockaddr *)&sin, &len)) < 0)
return 1;
+
+ rtp->rxcount++;
+
+ /* Schedule RTCP report transmissions if possible */
+ ast_rtcp_schedule(rtp);
header = (unsigned int *)(rtp->rawdata + AST_FRIENDLY_OFFSET);
@@ -3386,11 +3590,18 @@
}
/* Steal the file descriptors from the channel and stash them away */
- fds[0] = chan->fds[0];
+ fds[0] = chan->fds[0]; /* RTP */
+ fds[1] = chan->fds[1]; /* RTCP */
chan->fds[0] = -1;
+ chan->fds[1] = -1;
/* Now, fire up callback mode */
iod[0] = ast_io_add(rtp->io, fds[0], p2p_rtp_callback, AST_IO_IN, rtp);
+ iod[1] = ast_io_add(rtp->ioc, fds[1], p2p_rtcp_callback, AST_IO_IN, rtp);
+
+ /* Kick the RTCP stream going by sending one empty stupid little packet */
+ ast_rtcp_write_empty(rtp, rtp->rtcp->s);
+ ast_log(LOG_DEBUG, "--- Enabled p2p callback for RTCP reads \n");
return 1;
}
@@ -3408,14 +3619,18 @@
/* Remove the callback from the IO context */
ast_io_remove(rtp->io, iod[0]);
+ ast_io_remove(rtp->iortcp, iod[1]);
/* Restore file descriptors */
chan->fds[0] = fds[0];
+ chan->fds[1] = fds[1];
ast_channel_unlock(chan);
/* Restore callback mode if previously used */
- if (ast_test_flag(rtp, FLAG_CALLBACK_MODE))
+ if (ast_test_flag(rtp, FLAG_CALLBACK_MODE)) {
rtp->ioid = ast_io_add(rtp->io, rtp->s, rtpread, AST_IO_IN, rtp);
+ rtp->ioidrtcp = ast_io_add(rtp->iortcp, fds[1], p2p_rtcp_callback, AST_IO_IN, rtp);
+ }
return 0;
}
@@ -3453,6 +3668,10 @@
/* Now let go of the channel locks and be on our way */
ast_channel_unlock(c0);
ast_channel_unlock(c1);
+
+ /* Kick the RTCP stream going by sending one empty stupid little packet */
+ ast_rtcp_write_empty(p0, p0->rtcp->s);
+ ast_rtcp_write_empty(p1, p1->rtcp->s);
/* Go into a loop forwarding frames until we don't need to anymore */
cs[0] = c0;
Modified: team/oej/pinefrog-1.4/utils/Makefile
URL: http://svnview.digium.com/svn/asterisk/team/oej/pinefrog-1.4/utils/Makefile?view=diff&rev=238580&r1=238579&r2=238580
==============================================================================
--- team/oej/pinefrog-1.4/utils/Makefile (original)
+++ team/oej/pinefrog-1.4/utils/Makefile Fri Jan 8 10:02:32 2010
@@ -30,6 +30,11 @@
UTILS:=$(ALL_UTILS)
include $(ASTTOPDIR)/Makefile.rules
+
+ifneq ($(findstring darwin,$(OSARCH)),)
+ _ASTCFLAGS+=-D__Darwin__
+ AUDIO_LIBS=-framework CoreAudio
+endif
ifeq ($(OSARCH),SunOS)
LIBS+=-lsocket -lnsl
More information about the asterisk-commits
mailing list