aboutsummaryrefslogtreecommitdiffstats
path: root/openbsc/src/libmgcp/mgcp_network.c
diff options
context:
space:
mode:
authorHolger Hans Peter Freyther <zecke@selfish.org>2012-10-22 17:30:12 +0200
committerHolger Hans Peter Freyther <zecke@selfish.org>2012-11-12 10:42:05 +0100
commit769912c9e95e9247831c51e6f7592b07712709d3 (patch)
treec0f1caab0d411932fed48aad41dc2a5813c582ec /openbsc/src/libmgcp/mgcp_network.c
parent1e85af661caf8150199eded75791b15142c81acd (diff)
mgcp: Calculate the wrap around as of Appendix A in RFC 3550
This is missing the probation and the dealing with a remote restart. For the remote restart we will simply write a log statement as this is unlikely to happen during a call or if it does happen the call will be taken down by the BSC anyway.
Diffstat (limited to 'openbsc/src/libmgcp/mgcp_network.c')
-rw-r--r--openbsc/src/libmgcp/mgcp_network.c21
1 files changed, 20 insertions, 1 deletions
diff --git a/openbsc/src/libmgcp/mgcp_network.c b/openbsc/src/libmgcp/mgcp_network.c
index 85d03090a..233418b87 100644
--- a/openbsc/src/libmgcp/mgcp_network.c
+++ b/openbsc/src/libmgcp/mgcp_network.c
@@ -73,6 +73,10 @@ struct rtp_hdr {
uint32_t ssrc;
} __attribute__((packed));
+#define RTP_SEQ_MOD (1 << 16)
+#define RTP_MAX_DROPOUT 3000
+#define RTP_MAX_MISORDER 100
+
enum {
DEST_NETWORK = 0,
@@ -116,7 +120,7 @@ int mgcp_send_dummy(struct mgcp_endpoint *endp)
static void patch_and_count(struct mgcp_endpoint *endp, struct mgcp_rtp_state *state,
int payload, struct sockaddr_in *addr, char *data, int len)
{
- uint16_t seq;
+ uint16_t seq, udelta;
uint32_t timestamp;
struct rtp_hdr *rtp_hdr;
@@ -154,6 +158,21 @@ static void patch_and_count(struct mgcp_endpoint *endp, struct mgcp_rtp_state *s
rtp_hdr->timestamp = htonl(timestamp);
}
+ /*
+ * The below takes the shape of the validation from Appendix A. Check
+ * if there is something weird with the sequence number, otherwise check
+ * for a wrap around in the sequence number.
+ */
+ udelta = seq - state->max_seq;
+ if (udelta < RTP_MAX_DROPOUT) {
+ if (seq < state->max_seq)
+ state->cycles += RTP_SEQ_MOD;
+ } else if (udelta <= RTP_SEQ_MOD + RTP_MAX_MISORDER) {
+ LOGP(DMGCP, LOGL_NOTICE,
+ "RTP seqno made a very large jump on 0x%x delta: %u\n",
+ ENDPOINT_NUMBER(endp), udelta);
+ }
+
state->max_seq = seq;
state->last_timestamp = timestamp;