aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorHolger Hans Peter Freyther <zecke@selfish.org>2010-07-29 02:38:39 +0800
committerHolger Hans Peter Freyther <zecke@selfish.org>2010-07-29 02:41:38 +0800
commit380b8711a2c3a7bc88ee3cc692c2f51e019b8859 (patch)
treed12a01f56b80b2e491a7a085187c245d05b612fd
parent12b917d8390c4f8004beda1a465f93509323a058 (diff)
mgcp: Attempt to count missing RTP packets with a basic calculation
This code compares the UDP sequence numbers of two RTP messages and guesses if packets are missing. It is guessing in two ways: 1.) by default the sequence number is 0, so on the first value we ignore the jump... we might ignore a real issue in case of a wrap around which is easily possible as the sequence should be a random number. 2.) the UDP stream might have been reordered on the network and we would see the jump... In any case these two shortcomings are acceptable for the feature that is meant to provide some basic analysis..
-rw-r--r--openbsc/include/openbsc/mgcp_internal.h6
-rw-r--r--openbsc/src/mgcp/mgcp_network.c22
-rw-r--r--openbsc/src/mgcp/mgcp_protocol.c3
3 files changed, 27 insertions, 4 deletions
diff --git a/openbsc/include/openbsc/mgcp_internal.h b/openbsc/include/openbsc/mgcp_internal.h
index d5aec3080..918ba4b2f 100644
--- a/openbsc/include/openbsc/mgcp_internal.h
+++ b/openbsc/include/openbsc/mgcp_internal.h
@@ -61,6 +61,12 @@ struct mgcp_endpoint {
/* statistics */
unsigned int in_bts;
unsigned int in_remote;
+
+ /* sequence bits */
+ uint16_t net_seq_no;
+ uint16_t bts_seq_no;
+ int net_lost_no;
+ int bts_lost_no;
};
#define ENDPOINT_NUMBER(endp) abs(endp - endp->cfg->endpoints)
diff --git a/openbsc/src/mgcp/mgcp_network.c b/openbsc/src/mgcp/mgcp_network.c
index 6e6b7a663..137aa9388 100644
--- a/openbsc/src/mgcp/mgcp_network.c
+++ b/openbsc/src/mgcp/mgcp_network.c
@@ -94,17 +94,29 @@ int mgcp_send_dummy(struct mgcp_endpoint *endp)
endp->net_rtp, buf, 1);
}
-static void patch_payload(int payload, char *data, int len)
+static void patch_and_count(uint16_t *last_seq, int *lost, int payload, char *data, int len)
{
+ uint16_t seq;
struct rtp_hdr *rtp_hdr;
if (len < sizeof(*rtp_hdr))
return;
+ rtp_hdr = (struct rtp_hdr *) data;
+ seq = ntohs(rtp_hdr->sequence);
+
+ /* 0 is assumed to be not set */
+ if (*last_seq == 0)
+ *last_seq = seq;
+ else if (*last_seq + 1 != seq)
+ *lost += abs(*last_seq - seq);
+
+ *last_seq = seq;
+
+
if (payload < 0)
return;
- rtp_hdr = (struct rtp_hdr *) data;
rtp_hdr->payload_type = payload;
}
@@ -194,13 +206,15 @@ static int rtp_data_cb(struct bsc_fd *fd, unsigned int what)
if (dest == DEST_NETWORK) {
if (proto == PROTO_RTP)
- patch_payload(endp->net_payload_type, buf, rc);
+ patch_and_count(&endp->bts_seq_no, &endp->bts_lost_no,
+ endp->net_payload_type, buf, rc);
return udp_send(fd->fd, &endp->remote,
proto == PROTO_RTP ? endp->net_rtp : endp->net_rtcp,
buf, rc);
} else {
if (proto == PROTO_RTP)
- patch_payload(endp->bts_payload_type, buf, rc);
+ patch_and_count(&endp->net_seq_no, &endp->net_lost_no,
+ endp->bts_payload_type, buf, rc);
return udp_send(fd->fd, &endp->bts,
proto == PROTO_RTP ? endp->bts_rtp : endp->bts_rtcp,
buf, rc);
diff --git a/openbsc/src/mgcp/mgcp_protocol.c b/openbsc/src/mgcp/mgcp_protocol.c
index d82bd68f9..8131277ac 100644
--- a/openbsc/src/mgcp/mgcp_protocol.c
+++ b/openbsc/src/mgcp/mgcp_protocol.c
@@ -764,4 +764,7 @@ void mgcp_free_endp(struct mgcp_endpoint *endp)
endp->in_bts = endp->in_remote = 0;
memset(&endp->remote, 0, sizeof(endp->remote));
memset(&endp->bts, 0, sizeof(endp->bts));
+
+ endp->net_seq_no = endp->bts_seq_no = 0;
+ endp->net_lost_no = endp->bts_lost_no = 0;
}