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.
diff --git a/openbsc/src/libmgcp/mgcp_network.c b/openbsc/src/libmgcp/mgcp_network.c
index 85d0309..233418b 100644
--- a/openbsc/src/libmgcp/mgcp_network.c
+++ b/openbsc/src/libmgcp/mgcp_network.c
@@ -73,6 +73,10 @@
 	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 @@
 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 @@
 		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;