Commit d9c39998 authored by Ghislain MARY's avatar Ghislain MARY

Fill TTL/HL fields in RTCP XR stat-summary packets.

parent eb73ce02
......@@ -143,6 +143,12 @@ typedef struct OrtpRtcpXrStats {
uint16_t rcv_seq_at_last_stat_summary; /* Received sequence number at last XR stat-summary sent */
uint32_t rcv_since_last_stat_summary; /* The number of packets received since last XR stat-summary was sent */
uint32_t dup_since_last_stat_summary; /* The number of duplicate packets received since last XR stat-summary was sent */
double olds_ttl_or_hl_since_last_stat_summary;
double oldm_ttl_or_hl_since_last_stat_summary;
double news_ttl_or_hl_since_last_stat_summary;
double newm_ttl_or_hl_since_last_stat_summary;
uint8_t min_ttl_or_hl_since_last_stat_summary; /* The minimum value of TTL/HL since last XR stat-summary was sent */
uint8_t max_ttl_or_hl_since_last_stat_summary; /* The maximum value of TTL/HL since last XR stat-summary was sent */
} OrtpRtcpXrStats;
typedef struct _RtpStream
......
......@@ -60,6 +60,7 @@ typedef struct msgb
struct timeval timestamp;
#endif
ortp_recv_addr_t recv_addr;
uint8_t ttl_or_hl;
} mblk_t;
......
......@@ -596,7 +596,12 @@ static int rtcp_xr_stat_summary_init(uint8_t *buf, RtpSession *session) {
block->dev_jitter = htonl(0);
}
if (flags & (OrtpRtcpXrStatSummaryTTL | OrtpRtcpXrStatSummaryHL)) {
/* TODO */
block->min_ttl_or_hl = session->rtcp_xr_stats.min_ttl_or_hl_since_last_stat_summary;
block->max_ttl_or_hl = session->rtcp_xr_stats.max_ttl_or_hl_since_last_stat_summary;
block->mean_ttl_or_hl = (session->rtcp_xr_stats.rcv_since_last_stat_summary > 0)
? (uint8_t)session->rtcp_xr_stats.newm_ttl_or_hl_since_last_stat_summary : 0;
block->dev_ttl_or_hl = (session->rtcp_xr_stats.rcv_since_last_stat_summary > 1)
? (uint8_t)(session->rtcp_xr_stats.news_ttl_or_hl_since_last_stat_summary / (session->rtcp_xr_stats.rcv_since_last_stat_summary - 1)) : 0;
} else {
block->min_ttl_or_hl = 0;
block->max_ttl_or_hl = 0;
......
......@@ -198,6 +198,30 @@ void rtp_session_rtp_parse(RtpSession *session, mblk_t *mp, uint32_t local_str_t
rtpstream->hwrcv_seq_at_last_SR=rtp->seq_number;
session->rtcp_xr_stats.rcv_seq_at_last_stat_summary = rtp->seq_number;
}
/* TTL/HL statistics */
if (session->rtcp_xr_stats.rcv_since_last_stat_summary == 1) {
session->rtcp_xr_stats.min_ttl_or_hl_since_last_stat_summary = 255;
session->rtcp_xr_stats.max_ttl_or_hl_since_last_stat_summary = 0;
session->rtcp_xr_stats.olds_ttl_or_hl_since_last_stat_summary = 0;
session->rtcp_xr_stats.oldm_ttl_or_hl_since_last_stat_summary = mp->ttl_or_hl;
session->rtcp_xr_stats.newm_ttl_or_hl_since_last_stat_summary = mp->ttl_or_hl;
} else {
double x = (double) mp->ttl_or_hl;
double *olds = &session->rtcp_xr_stats.olds_ttl_or_hl_since_last_stat_summary;
double *oldm = &session->rtcp_xr_stats.oldm_ttl_or_hl_since_last_stat_summary;
double *news = &session->rtcp_xr_stats.news_ttl_or_hl_since_last_stat_summary;
double *newm = &session->rtcp_xr_stats.newm_ttl_or_hl_since_last_stat_summary;
*newm = *oldm + (x - *oldm) / session->rtcp_xr_stats.rcv_since_last_stat_summary;
*news = *olds + ((x - *oldm) * (x - *newm));
*oldm = *newm;
*olds = *news;
}
if (mp->ttl_or_hl < session->rtcp_xr_stats.min_ttl_or_hl_since_last_stat_summary) {
session->rtcp_xr_stats.min_ttl_or_hl_since_last_stat_summary = mp->ttl_or_hl;
}
if (mp->ttl_or_hl > session->rtcp_xr_stats.max_ttl_or_hl_since_last_stat_summary) {
session->rtcp_xr_stats.max_ttl_or_hl_since_last_stat_summary = mp->ttl_or_hl;
}
}
/* check for possible telephone events */
......
......@@ -133,6 +133,23 @@ static ortp_socket_t create_and_bind(const char *addr, int port, int *sock_famil
ortp_warning ("Fail to set rtp timestamp: %s.",getSocketError());
}
#endif
err = 0;
switch (res->ai_family) {
default:
case AF_INET:
#ifdef IP_RECVTTL
err = setsockopt(sock, SOL_IP, IP_RECVTTL, &optval, sizeof(optval));
#endif
break;
case AF_INET6:
#ifdef IPV6_RECVHOPLIMIT
err = setsockopt(sock, SOL_IPV6, IPV6_RECVHOPLIMIT, &optval, sizeof(optval));
#endif
break;
}
if (err < 0) {
ortp_warning("Fail to set recv TTL/HL socket option: %s.", getSocketError());
}
*sock_family=res->ai_family;
err = bind (sock, res->ai_addr, res->ai_addrlen);
......@@ -211,6 +228,10 @@ static ortp_socket_t create_and_bind(const char *addr, int port, int *sock_famil
ortp_warning ("Fail to set rtp timestamp: %s.",getSocketError());
}
#endif
err = setsockopt(sock, IPPROTO_IP, IP_RECVTTL, &optval, sizeof(optval));
if (err < 0) {
ortp_warning("Fail to set recv TTL socket option: %s.", getSocketError());
}
err = bind (sock,
(struct sockaddr *) &saddr,
......@@ -1214,6 +1235,18 @@ int rtp_session_rtp_recv_abstract(ortp_socket_t socket, mblk_t *msg, int flags,
memcpy(&msg->recv_addr.addr.ipi6_addr, ia, sizeof(msg->recv_addr.addr.ipi6_addr));
msg->recv_addr.family = AF_INET6;
}
#endif
#ifdef IP_RECVTTL
if ((cmsghdr->cmsg_level == SOL_IP) && (cmsghdr->cmsg_type == IP_TTL)) {
uint32_t *ptr = (uint32_t *)CMSG_DATA(cmsghdr);
msg->ttl_or_hl = (*ptr & 0xFF);
}
#endif
#ifdef IPV6_RECVHOPLIMIT
if ((cmsghdr->cmsg_level == SOL_IPV6) && (cmsghdr->cmsg_type == IPV6_HOPLIMIT)) {
uint32_t *ptr = (uint32_t *)CMSG_DATA(cmsghdr);
msg->ttl_or_hl = (*ptr & 0xFF);
}
#endif
}
}
......
......@@ -36,6 +36,7 @@ void mblk_init(mblk_t *mp)
#if defined(ORTP_TIMESTAMP)
memset(&(mp->timestamp), 0, sizeof(struct timeval));
#endif
mp->ttl_or_hl = 0;
}
void mblk_meta_copy(const mblk_t *source, mblk_t *dest) {
......@@ -44,6 +45,7 @@ void mblk_meta_copy(const mblk_t *source, mblk_t *dest) {
#if defined(ORTP_TIMESTAMP)
dest->timestamp = source->timestamp;
#endif
dest->ttl_or_hl = source->ttl_or_hl;
}
dblk_t *datab_alloc(size_t size){
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment