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/sdp/session.c b/src/sdp/session.c
new file mode 100644
index 0000000..f74cfe0
--- /dev/null
+++ b/src/sdp/session.c
@@ -0,0 +1,301 @@
+/**
+ * @file sdp/session.c SDP Session
+ *
+ * Copyright (C) 2010 Creytiv.com
+ */
+#include <re_types.h>
+#include <re_fmt.h>
+#include <re_mem.h>
+#include <re_mbuf.h>
+#include <re_list.h>
+#include <re_tmr.h>
+#include <re_sa.h>
+#include <re_sdp.h>
+#include <re_sys.h>
+#include "sdp.h"
+
+
+static void destructor(void *arg)
+{
+ struct sdp_session *sess = arg;
+
+ list_flush(&sess->lmedial);
+ list_flush(&sess->medial);
+ list_flush(&sess->rattrl);
+ list_flush(&sess->lattrl);
+}
+
+
+/**
+ * Allocate a new SDP Session
+ *
+ * @param sessp Pointer to allocated SDP Session object
+ * @param laddr Local network address
+ *
+ * @return 0 if success, otherwise errorcode
+ */
+int sdp_session_alloc(struct sdp_session **sessp, const struct sa *laddr)
+{
+ struct sdp_session *sess;
+ int err = 0, i;
+
+ if (!sessp || !laddr)
+ return EINVAL;
+
+ sess = mem_zalloc(sizeof(*sess), destructor);
+ if (!sess)
+ return ENOMEM;
+
+ sess->laddr = *laddr;
+ sess->id = rand_u32();
+ sess->ver = rand_u32() & 0x7fffffff;
+ sess->rdir = SDP_SENDRECV;
+
+ sa_init(&sess->raddr, AF_INET);
+
+ for (i=0; i<SDP_BANDWIDTH_MAX; i++) {
+ sess->lbwv[i] = -1;
+ sess->rbwv[i] = -1;
+ }
+
+ if (err)
+ mem_deref(sess);
+ else
+ *sessp = sess;
+
+ return err;
+}
+
+
+/**
+ * Reset the remote side of an SDP Session
+ *
+ * @param sess SDP Session
+ */
+void sdp_session_rreset(struct sdp_session *sess)
+{
+ int i;
+
+ if (!sess)
+ return;
+
+ sa_init(&sess->raddr, AF_INET);
+
+ list_flush(&sess->rattrl);
+
+ sess->rdir = SDP_SENDRECV;
+
+ for (i=0; i<SDP_BANDWIDTH_MAX; i++)
+ sess->rbwv[i] = -1;
+}
+
+
+/**
+ * Set the local network address of an SDP Session
+ *
+ * @param sess SDP Session
+ * @param laddr Local network address
+ */
+void sdp_session_set_laddr(struct sdp_session *sess, const struct sa *laddr)
+{
+ if (!sess || !laddr)
+ return;
+
+ sess->laddr = *laddr;
+}
+
+
+/**
+ * Set the local bandwidth of an SDP Session
+ *
+ * @param sess SDP Session
+ * @param type Bandwidth type
+ * @param bw Bandwidth value
+ */
+void sdp_session_set_lbandwidth(struct sdp_session *sess,
+ enum sdp_bandwidth type, int32_t bw)
+{
+ if (!sess || type >= SDP_BANDWIDTH_MAX)
+ return;
+
+ sess->lbwv[type] = bw;
+}
+
+
+/**
+ * Set a local attribute of an SDP Session
+ *
+ * @param sess SDP Session
+ * @param replace True to replace any existing attributes, false to append
+ * @param name Attribute name
+ * @param value Formatted attribute value
+ *
+ * @return 0 if success, otherwise errorcode
+ */
+int sdp_session_set_lattr(struct sdp_session *sess, bool replace,
+ const char *name, const char *value, ...)
+{
+ va_list ap;
+ int err;
+
+ if (!sess || !name)
+ return EINVAL;
+
+ if (replace)
+ sdp_attr_del(&sess->lattrl, name);
+
+ va_start(ap, value);
+ err = sdp_attr_addv(&sess->lattrl, name, value, ap);
+ va_end(ap);
+
+ return err;
+}
+
+
+/**
+ * Delete a local attribute of an SDP Session
+ *
+ * @param sess SDP Session
+ * @param name Attribute name
+ */
+void sdp_session_del_lattr(struct sdp_session *sess, const char *name)
+{
+ if (!sess || !name)
+ return;
+
+ sdp_attr_del(&sess->lattrl, name);
+}
+
+
+/**
+ * Get the local bandwidth of an SDP Session
+ *
+ * @param sess SDP Session
+ * @param type Bandwidth type
+ *
+ * @return Bandwidth value
+ */
+int32_t sdp_session_lbandwidth(const struct sdp_session *sess,
+ enum sdp_bandwidth type)
+{
+ if (!sess || type >= SDP_BANDWIDTH_MAX)
+ return 0;
+
+ return sess->lbwv[type];
+}
+
+
+/**
+ * Get the remote bandwidth of an SDP Session
+ *
+ * @param sess SDP Session
+ * @param type Bandwidth type
+ *
+ * @return Bandwidth value
+ */
+int32_t sdp_session_rbandwidth(const struct sdp_session *sess,
+ enum sdp_bandwidth type)
+{
+ if (!sess || type >= SDP_BANDWIDTH_MAX)
+ return 0;
+
+ return sess->rbwv[type];
+}
+
+
+/**
+ * Get a remote attribute of an SDP Session
+ *
+ * @param sess SDP Session
+ * @param name Attribute name
+ *
+ * @return Attribute value if exist, NULL if not exist
+ */
+const char *sdp_session_rattr(const struct sdp_session *sess, const char *name)
+{
+ if (!sess || !name)
+ return NULL;
+
+ return sdp_attr_apply(&sess->rattrl, name, NULL, NULL);
+}
+
+
+/**
+ * Apply a function handler of all matching remote attributes
+ *
+ * @param sess SDP Session
+ * @param name Attribute name
+ * @param attrh Attribute handler
+ * @param arg Handler argument
+ *
+ * @return Attribute value if match
+ */
+const char *sdp_session_rattr_apply(const struct sdp_session *sess,
+ const char *name,
+ sdp_attr_h *attrh, void *arg)
+{
+ if (!sess)
+ return NULL;
+
+ return sdp_attr_apply(&sess->rattrl, name, attrh, arg);
+}
+
+
+/**
+ * Get the list of media-lines from an SDP Session
+ *
+ * @param sess SDP Session
+ * @param local True for local, False for remote
+ *
+ * @return List of media-lines
+ */
+const struct list *sdp_session_medial(const struct sdp_session *sess,
+ bool local)
+{
+ if (!sess)
+ return NULL;
+
+ return local ? &sess->lmedial : &sess->medial;
+}
+
+
+/**
+ * Print SDP Session debug information
+ *
+ * @param pf Print function for output
+ * @param sess SDP Session
+ *
+ * @return 0 if success, otherwise errorcode
+ */
+int sdp_session_debug(struct re_printf *pf, const struct sdp_session *sess)
+{
+ struct le *le;
+ int err;
+
+ if (!sess)
+ return 0;
+
+ err = re_hprintf(pf, "SDP session\n");
+
+ err |= re_hprintf(pf, " local attributes:\n");
+
+ for (le=sess->lattrl.head; le; le=le->next)
+ err |= re_hprintf(pf, " %H\n", sdp_attr_debug, le->data);
+
+ err |= re_hprintf(pf, " remote attributes:\n");
+
+ for (le=sess->rattrl.head; le; le=le->next)
+ err |= re_hprintf(pf, " %H\n", sdp_attr_debug, le->data);
+
+ err |= re_hprintf(pf, "session media:\n");
+
+ for (le=sess->medial.head; le; le=le->next)
+ err |= sdp_media_debug(pf, le->data);
+
+ err |= re_hprintf(pf, "local media:\n");
+
+ for (le=sess->lmedial.head; le; le=le->next)
+ err |= sdp_media_debug(pf, le->data);
+
+ return err;
+}