Squashed 'third_party/rawrtc/re/' content from commit f3163ce8b

Change-Id: I6a235e6ac0f03269d951026f9d195da05c40fdab
git-subtree-dir: third_party/rawrtc/re
git-subtree-split: f3163ce8b526a13b35ef71ce4dd6f43585064d8a
diff --git a/src/srtp/stream.c b/src/srtp/stream.c
new file mode 100644
index 0000000..21393d8
--- /dev/null
+++ b/src/srtp/stream.c
@@ -0,0 +1,109 @@
+/**
+ * @file srtp/stream.c  Secure Real-time Transport Protocol (SRTP) -- stream
+ *
+ * Copyright (C) 2010 Creytiv.com
+ */
+#include <re_types.h>
+#include <re_mem.h>
+#include <re_mbuf.h>
+#include <re_list.h>
+#include <re_aes.h>
+#include <re_srtp.h>
+#include "srtp.h"
+
+
+/** SRTP protocol values */
+#ifndef SRTP_MAX_STREAMS
+#define SRTP_MAX_STREAMS  (8)  /**< Maximum number of SRTP streams */
+#endif
+
+
+static void stream_destructor(void *arg)
+{
+	struct srtp_stream *strm = arg;
+
+	list_unlink(&strm->le);
+}
+
+
+static struct srtp_stream *stream_find(struct srtp *srtp, uint32_t ssrc)
+{
+	struct le *le;
+
+	for (le = srtp->streaml.head; le; le = le->next) {
+
+		struct srtp_stream *strm = le->data;
+
+		if (strm->ssrc == ssrc)
+			return strm;
+	}
+
+	return NULL;
+}
+
+
+static int stream_new(struct srtp_stream **strmp, struct srtp *srtp,
+		      uint32_t ssrc)
+{
+	struct srtp_stream *strm;
+
+	if (list_count(&srtp->streaml) >= SRTP_MAX_STREAMS)
+		return ENOSR;
+
+	strm = mem_zalloc(sizeof(*strm), stream_destructor);
+	if (!strm)
+		return ENOMEM;
+
+	strm->ssrc = ssrc;
+	srtp_replay_init(&strm->replay_rtp);
+	srtp_replay_init(&strm->replay_rtcp);
+
+	list_append(&srtp->streaml, &strm->le, strm);
+
+	if (strmp)
+		*strmp = strm;
+
+	return 0;
+}
+
+
+int stream_get(struct srtp_stream **strmp, struct srtp *srtp, uint32_t ssrc)
+{
+	struct srtp_stream *strm;
+
+	if (!strmp || !srtp)
+		return EINVAL;
+
+	strm = stream_find(srtp, ssrc);
+	if (strm) {
+		*strmp = strm;
+		return 0;
+	}
+
+	return stream_new(strmp, srtp, ssrc);
+}
+
+
+int stream_get_seq(struct srtp_stream **strmp, struct srtp *srtp,
+		   uint32_t ssrc, uint16_t seq)
+{
+	struct srtp_stream *strm;
+	int err;
+
+	if (!strmp || !srtp)
+		return EINVAL;
+
+	err = stream_get(&strm, srtp, ssrc);
+	if (err)
+		return err;
+
+	/* Set the initial sequence number once only */
+	if (!strm->s_l_set) {
+		strm->s_l = seq;
+		strm->s_l_set = true;
+	}
+
+	*strmp = strm;
+
+	return 0;
+}