aboutsummaryrefslogtreecommitdiffstats
path: root/channels
diff options
context:
space:
mode:
authorbbryant <bbryant@f38db490-d61c-443f-a65b-d21fe96a405b>2008-06-05 16:24:19 +0000
committerbbryant <bbryant@f38db490-d61c-443f-a65b-d21fe96a405b>2008-06-05 16:24:19 +0000
commit68dea9b6d66ac8281286c8fd85d3ef4b1ed3a823 (patch)
treed1e5ce5e2319e18edd672e98cdfaae3e096a1e2e /channels
parente387c61e4f71e932c9a81269c34c93b4ff92f0fb (diff)
This patch adds more detailed statistics for RTP channels, and provides an API call to access it, including maximums, minimums, standard deviatinos,
and normal deviations. Currently this is implemented for chan_sip, but could be added to the func_channel_read callbacks for the CHANNEL function for any channel that uses RTP. (closes issue #10590) Reported by: gasparz Patches: chan_sip_c.diff uploaded by gasparz (license 219) rtp_c.diff uploaded by gasparz (license 219) rtp_h.diff uploaded by gasparz (license 219) audioqos-trunk.diff uploaded by snuffy (license 35) rtpqos-trunk-r119891.diff uploaded by sergee (license 138) Tested by: jsmith, gasparz, snuffy, marsosa, chappell, sergee git-svn-id: http://svn.digium.com/svn/asterisk/trunk@120635 f38db490-d61c-443f-a65b-d21fe96a405b
Diffstat (limited to 'channels')
-rw-r--r--channels/chan_sip.c69
1 files changed, 55 insertions, 14 deletions
diff --git a/channels/chan_sip.c b/channels/chan_sip.c
index 61a981abe..737927918 100644
--- a/channels/chan_sip.c
+++ b/channels/chan_sip.c
@@ -5063,15 +5063,25 @@ static int sip_hangup(struct ast_channel *ast)
}
} else { /* Call is in UP state, send BYE */
if (!p->pendinginvite) {
+ struct ast_channel *bridge = ast_bridged_channel(oldowner);
char *audioqos = "";
char *videoqos = "";
char *textqos = "";
+
if (p->rtp)
- audioqos = ast_rtp_get_quality(p->rtp, NULL);
+ ast_rtp_set_vars(oldowner, p->rtp);
+
+ if (bridge) {
+ struct sip_pvt *q = bridge->tech_pvt;
+
+ if (IS_SIP_TECH(bridge->tech) && q->rtp)
+ ast_rtp_set_vars(bridge, q->rtp);
+ }
+
if (p->vrtp)
- videoqos = ast_rtp_get_quality(p->vrtp, NULL);
+ videoqos = ast_rtp_get_quality(p->vrtp, NULL, RTPQOS_SUMMARY);
if (p->trtp)
- textqos = ast_rtp_get_quality(p->trtp, NULL);
+ textqos = ast_rtp_get_quality(p->trtp, NULL, RTPQOS_SUMMARY);
/* Send a hangup */
transmit_request_with_auth(p, SIP_BYE, 0, XMIT_RELIABLE, 1);
@@ -18429,10 +18439,13 @@ static int acf_channel_read(struct ast_channel *chan, const char *funcname, char
ast_rtp_get_peer(p->vrtp, &sin);
else if (!strcasecmp(args.type, "text"))
ast_rtp_get_peer(p->trtp, &sin);
+ else
+ return -1;
snprintf(buf, buflen, "%s:%d", ast_inet_ntoa(sin.sin_addr), ntohs(sin.sin_port));
} else if (!strcasecmp(args.param, "rtpqos")) {
struct ast_rtp_quality qos;
+ struct ast_rtp *rtp = p->rtp;
memset(&qos, 0, sizeof(qos));
@@ -18442,11 +18455,13 @@ static int acf_channel_read(struct ast_channel *chan, const char *funcname, char
args.field = "all";
if (strcasecmp(args.type, "AUDIO") == 0) {
- all = ast_rtp_get_quality(p->rtp, &qos);
+ all = ast_rtp_get_quality(rtp = p->rtp, &qos, RTPQOS_SUMMARY);
} else if (strcasecmp(args.type, "VIDEO") == 0) {
- all = ast_rtp_get_quality(p->vrtp, &qos);
+ all = ast_rtp_get_quality(rtp = p->vrtp, &qos, RTPQOS_SUMMARY);
} else if (strcasecmp(args.type, "TEXT") == 0) {
- all = ast_rtp_get_quality(p->trtp, &qos);
+ all = ast_rtp_get_quality(rtp = p->trtp, &qos, RTPQOS_SUMMARY);
+ } else {
+ return -1;
}
if (strcasecmp(args.field, "local_ssrc") == 0)
@@ -18469,6 +18484,8 @@ static int acf_channel_read(struct ast_channel *chan, const char *funcname, char
snprintf(buf, buflen, "%.0f", qos.rtt * 1000.0);
else if (strcasecmp(args.field, "all") == 0)
ast_copy_string(buf, all, buflen);
+ else if (!ast_rtp_get_qos(rtp, args.field, buf, buflen))
+ ;
else {
ast_log(LOG_WARNING, "Unrecognized argument '%s' to %s\n", preparse, funcname);
return -1;
@@ -18501,23 +18518,47 @@ static int handle_request_bye(struct sip_pvt *p, struct sip_request *req)
/* Get RTCP quality before end of call */
if (p->do_history || p->owner) {
- char *audioqos, *videoqos, *textqos;
- if (p->rtp) {
- audioqos = ast_rtp_get_quality(p->rtp, NULL);
- if (p->do_history)
+ struct ast_channel *bridge = ast_bridged_channel(p->owner);
+ char *videoqos, *textqos;
+
+ if (p->rtp) {
+ if (p->do_history) {
+ char *audioqos,
+ *audioqos_jitter,
+ *audioqos_loss,
+ *audioqos_rtt;
+
+ audioqos = ast_rtp_get_quality(p->rtp, NULL, RTPQOS_SUMMARY);
+ audioqos_jitter = ast_rtp_get_quality(p->rtp, NULL, RTPQOS_JITTER);
+ audioqos_loss = ast_rtp_get_quality(p->rtp, NULL, RTPQOS_LOSS);
+ audioqos_rtt = ast_rtp_get_quality(p->rtp, NULL, RTPQOS_RTT);
+
append_history(p, "RTCPaudio", "Quality:%s", audioqos);
- if (p->owner)
- pbx_builtin_setvar_helper(p->owner, "RTPAUDIOQOS", audioqos);
+ append_history(p, "RTCPaudioJitter", "Quality:%s", audioqos_jitter);
+ append_history(p, "RTCPaudioLoss", "Quality:%s", audioqos_loss);
+ append_history(p, "RTCPaudioRTT", "Quality:%s", audioqos_rtt);
+ }
+
+ ast_rtp_set_vars(p->owner, p->rtp);
}
+
+ if (bridge) {
+ struct sip_pvt *q = bridge->tech_pvt;
+
+ if (IS_SIP_TECH(bridge->tech) && q->rtp)
+ ast_rtp_set_vars(bridge, q->rtp);
+ }
+
if (p->vrtp) {
- videoqos = ast_rtp_get_quality(p->vrtp, NULL);
+ videoqos = ast_rtp_get_quality(p->vrtp, NULL, RTPQOS_SUMMARY);
if (p->do_history)
append_history(p, "RTCPvideo", "Quality:%s", videoqos);
if (p->owner)
pbx_builtin_setvar_helper(p->owner, "RTPVIDEOQOS", videoqos);
}
+
if (p->trtp) {
- textqos = ast_rtp_get_quality(p->trtp, NULL);
+ textqos = ast_rtp_get_quality(p->trtp, NULL, RTPQOS_SUMMARY);
if (p->do_history)
append_history(p, "RTCPtext", "Quality:%s", textqos);
if (p->owner)